93 lines
2.8 KiB
Rust
93 lines
2.8 KiB
Rust
|
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<T: Read>(reader: &mut T) -> Result<Self, Error> {
|
||
|
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<T: 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(())
|
||
|
}
|
||
|
}
|