use { crate::{Error, File, Special}, std::io::{Read, Write}, }; #[repr(u8)] #[derive(Debug)] pub enum FileType { Normal(File), HardLink(String), SoftLink(String), Directory, Character(Special), Block(Special), Fifo, } impl FileType { pub fn read(reader: &mut T) -> Result { let mut buf = [0; 1]; reader.read_exact(&mut buf)?; match buf[0] { 0 => { let file = File::read(reader)?; Ok(Self::Normal(file)) } 1 => { let mut len = [0; 8]; reader.read_exact(&mut len)?; let len = u64::from_le_bytes(len); let mut buf = Vec::with_capacity(len.try_into()?); let mut handle = reader.take(len); handle.read_exact(&mut buf)?; let s = String::from_utf8(buf)?; Ok(Self::HardLink(s)) } 2 => { let mut len = [0; 8]; reader.read_exact(&mut len)?; let len = u64::from_le_bytes(len); let mut buf = Vec::with_capacity(len.try_into()?); let mut handle = reader.take(len); handle.read_exact(&mut buf)?; let s = String::from_utf8(buf)?; Ok(Self::SoftLink(s)) } 3 => Ok(Self::Directory), 4 => { let sp = Special::read(reader)?; Ok(Self::Character(sp)) } 5 => { let sp = Special::read(reader)?; Ok(Self::Block(sp)) } 6 => Ok(Self::Fifo), _ => Err(Error::UnknownFileType), } } pub fn write(&self, writer: &mut T) -> Result<(), Error> { match self { Self::Normal(f) => { writer.write_all(&[0])?; f.write(writer)?; } Self::HardLink(s) => { writer.write_all(&[1])?; let len = s.len() as u64; writer.write_all(&len.to_le_bytes())?; writer.write_all(s.as_bytes())?; } Self::SoftLink(s) => { writer.write_all(&[2])?; let len = s.len() as u64; writer.write_all(&len.to_le_bytes())?; writer.write_all(s.as_bytes())?; } Self::Directory => writer.write_all(&[3])?, Self::Character(s) => { writer.write_all(&[4])?; s.write(writer)?; } Self::Block(s) => { writer.write_all(&[5])?; s.write(writer)?; } Self::Fifo => writer.write_all(&[6])?, } Ok(()) } }