1use std::fs::Metadata;
2use std::os::unix::fs::MetadataExt as _;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum FileMode {
7 Regular,
9 Executable,
11 Symlink,
13}
14
15impl FileMode {
16 const REGULAR_BITS: u32 = 0o100_644;
17 const EXECUTABLE_BITS: u32 = 0o100_755;
18 const SYMLINK_BITS: u32 = 0o120_000;
19 const TYPE_MASK: u32 = 0o170_000;
20 const OWNER_EXECUTE: u32 = 0o100;
21
22 pub(crate) const fn from_git(raw: u32) -> Self {
24 if raw & Self::TYPE_MASK == Self::SYMLINK_BITS {
25 Self::Symlink
26 } else if raw & Self::OWNER_EXECUTE != 0 {
27 Self::Executable
28 } else {
29 Self::Regular
30 }
31 }
32
33 pub(crate) fn from_metadata(metadata: &Metadata) -> Self {
35 if metadata.file_type().is_symlink() {
36 Self::Symlink
37 } else if metadata.mode() & Self::OWNER_EXECUTE != 0 {
38 Self::Executable
39 } else {
40 Self::Regular
41 }
42 }
43
44 #[must_use]
46 pub const fn bits(self) -> u32 {
47 match self {
48 Self::Regular => Self::REGULAR_BITS,
49 Self::Executable => Self::EXECUTABLE_BITS,
50 Self::Symlink => Self::SYMLINK_BITS,
51 }
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq)]
59pub struct FileEntry {
60 pub content: Vec<u8>,
62 pub mode: FileMode,
64}