use super::ArchiveEntity;
use crate::GlobalsFinal;
use anyhow::Result as AResult;
use std::path::Path;
use tar::Header;
pub(super) enum NewHeader<'a, 'b> {
Primary {
header: Header,
path: &'a Path,
},
Link {
header: Header,
path: &'a Path,
target: &'b Path,
},
}
impl<'a> NewHeader<'a, 'a> {
pub(super) fn create(entity: &'a ArchiveEntity, globals: &GlobalsFinal) -> AResult<Self> {
let mut header = Header::new_gnu();
let uid = globals.remap_uid(entity.header.uid()?)?;
header.set_uid(uid);
let gid = globals.remap_gid(entity.header.gid()?)?;
header.set_gid(gid);
header.set_size(entity.header.size()?);
header.set_mtime(entity.meta.mtime);
header.set_entry_type(entity.header.entry_type());
header.set_mode(entity.header.mode()?);
{
let header = header
.as_gnu_mut()
.ok_or(anyhow::anyhow!("Failed to convert header type"))?;
if let Some(atime) = entity.meta.atime {
header.set_atime(atime);
}
if let Some(ctime) = entity.meta.ctime {
header.set_ctime(ctime);
}
match entity.header.device_major() {
Ok(Some(x)) => header.set_device_major(x),
Err(_) => log::trace!("Decode error: Device major"),
_ => (),
}
match entity.header.device_minor() {
Ok(Some(x)) => header.set_device_minor(x),
Err(_) => log::trace!("Decode error: Device minor"),
_ => (),
}
if let Some(x) = entity.header.username()? {
header.set_username(x)?;
}
if let Some(x) = entity.header.groupname()? {
header.set_groupname(x)?;
}
}
let path = entity.path();
let result = if entity.is_link() {
let target = entity.target().unwrap();
Self::Link {
header,
path,
target,
}
} else {
Self::Primary { header, path }
};
Ok(result)
}
}