diff --git a/src/filetype.rs b/src/filetype.rs index cde8413..1253042 100644 --- a/src/filetype.rs +++ b/src/filetype.rs @@ -3,15 +3,16 @@ use { std::io::{Read, Write}, }; +#[repr(u8)] pub(crate) enum Flag { - Normal, - HardLink, - SoftLink, - Directory, - Character, - Block, - Fifo, - Eof, + Normal = 0, + HardLink = 1, + SoftLink = 2, + Directory = 3, + Character = 4, + Block = 5, + Fifo = 6, + Eof = 7, } impl TryFrom for Flag { @@ -32,6 +33,28 @@ impl TryFrom for Flag { } } +impl From<&FileType> for Flag { + fn from(value: &FileType) -> Self { + match value { + FileType::Normal(_) => Self::Normal, + FileType::HardLink(_) => Self::HardLink, + FileType::SoftLink(_) => Self::SoftLink, + FileType::Directory => Self::Directory, + FileType::Character(_) => Self::Character, + FileType::Block(_) => Self::Block, + FileType::Fifo => Self::Fifo, + FileType::Eof => Self::Eof, + } + } +} + +impl Flag { + pub(crate) fn append_mode(&self, mode: u16) -> u16 { + let mask: u16 = u16::from(*self as u8) << 13; + mode & mask + } +} + /// An enum representing the type of file of an archive member #[derive(Debug)] pub enum FileType { diff --git a/src/node.rs b/src/node.rs index f2d497d..fb05b86 100644 --- a/src/node.rs +++ b/src/node.rs @@ -108,11 +108,12 @@ impl Node { let len: u16 = self.name.len().try_into()?; writer.write_all(&len.to_le_bytes())?; writer.write_all(self.name.as_bytes())?; - writer.write_all(&self.mode.to_le_bytes())?; [self.uid, self.gid] .iter() .try_for_each(|f| writer.write_all(&f.to_le_bytes()))?; writer.write_all(&self.mtime.to_le_bytes())?; + let mode = Flag::from(&self.filetype).append_mode(self.mode); + writer.write_all(&mode.to_le_bytes())?; self.filetype.write(writer)?; Ok(()) }