pub mod raw;
use crate::{
BasicTarError,
header::raw::{ StringExt, U64Ext, Checksum }
};
#[derive(Default, Debug, Clone, Eq, PartialEq)]
pub struct Header {
pub path: String,
pub mode: Option<u64>,
pub uid: Option<u64>,
pub gid: Option<u64>,
pub size: u64,
pub mtime: Option<u64>,
pub typeflag: u8,
pub linkname: Option<String>
}
impl Header {
pub fn parse(data: raw::header::Raw) -> Result<Self, BasicTarError> {
if data.as_ref() == raw::header::raw().as_ref() {
Err(BasicTarError::EmptyHeader)?
}
let tar = raw::header::Header::from(data);
Checksum::verify(&tar)?;
let path = String::from_field(&tar.name)?;
let mode = Option::from_octal_field(&tar.mode)?;
let uid = Option::from_octal_field(&tar.uid)?;
let gid = Option::from_octal_field(&tar.gid)?;
let size = u64::from_octal_field(&tar.size)?;
let mtime = Option::from_octal_field(&tar.mtime)?;
let linkname = Option::from_field(&tar.linkname)?;
Ok(Self{ path, mode, uid, gid, size, typeflag: tar.typeflag[0], mtime, linkname })
}
pub fn serialize(self) -> Result<raw::header::Raw, BasicTarError> {
let mut tar = raw::header::header();
self.path.into_field(&mut tar.name)?;
self.mode.into_octal_field(&mut tar.mode)?;
self.uid.into_octal_field(&mut tar.uid)?;
self.gid.into_octal_field(&mut tar.gid)?;
self.size.into_octal_field(&mut tar.size)?;
self.mtime.into_octal_field(&mut tar.mtime)?;
tar.typeflag[0] = self.typeflag;
self.linkname.into_field(&mut tar.linkname)?;
Checksum::write(&mut tar);
Ok(tar.into())
}
}