use crate::{compression::Compression, path::BoxPath, AttrMap};
use crate::file::{BoxMetadata, Inode};
use std::num::NonZeroU64;
#[derive(Debug)]
pub enum Record {
File(FileRecord),
Directory(DirectoryRecord),
Link(LinkRecord),
}
impl Record {
#[inline(always)]
pub fn as_file(&self) -> Option<&FileRecord> {
match self {
Record::File(file) => Some(file),
_ => None,
}
}
#[inline(always)]
pub fn as_file_mut(&mut self) -> Option<&mut FileRecord> {
match self {
Record::File(file) => Some(file),
_ => None,
}
}
#[inline(always)]
pub fn as_directory(&self) -> Option<&DirectoryRecord> {
match self {
Record::Directory(dir) => Some(dir),
_ => None,
}
}
#[inline(always)]
pub fn as_directory_mut(&mut self) -> Option<&mut DirectoryRecord> {
match self {
Record::Directory(dir) => Some(dir),
_ => None,
}
}
#[inline(always)]
pub fn as_link(&self) -> Option<&LinkRecord> {
match self {
Record::Link(link) => Some(link),
_ => None,
}
}
#[inline(always)]
pub fn as_link_mut(&mut self) -> Option<&mut LinkRecord> {
match self {
Record::Link(link) => Some(link),
_ => None,
}
}
#[inline(always)]
pub fn name(&self) -> &str {
match self {
Record::File(file) => &*file.name,
Record::Directory(dir) => &*dir.name,
Record::Link(link) => &*link.name,
}
}
#[inline(always)]
pub fn attr<S: AsRef<str>>(&self, metadata: &BoxMetadata, key: S) -> Option<&[u8]> {
let key = metadata.attr_key(key.as_ref())?;
self.attrs().get(&key).map(|x| &**x)
}
#[inline(always)]
pub(crate) fn attrs(&self) -> &AttrMap {
match self {
Record::Directory(dir) => &dir.attrs,
Record::File(file) => &file.attrs,
Record::Link(link) => &link.attrs,
}
}
#[inline(always)]
pub(crate) fn attrs_mut(&mut self) -> &mut AttrMap {
match self {
Record::Directory(dir) => &mut dir.attrs,
Record::File(file) => &mut file.attrs,
Record::Link(link) => &mut link.attrs,
}
}
}
#[derive(Debug)]
pub struct LinkRecord {
pub name: String,
pub target: BoxPath,
pub attrs: AttrMap,
}
impl LinkRecord {
#[inline(always)]
pub fn attr<S: AsRef<str>>(&self, metadata: &BoxMetadata, key: S) -> Option<&[u8]> {
let key = metadata.attr_key(key.as_ref())?;
self.attrs.get(&key).map(|x| &**x)
}
#[inline(always)]
pub fn upcast(self) -> Record {
Record::Link(self)
}
}
#[derive(Debug)]
pub struct DirectoryRecord {
pub name: String,
pub inodes: Vec<Inode>,
pub attrs: AttrMap,
}
impl DirectoryRecord {
pub fn new(name: String) -> DirectoryRecord {
DirectoryRecord {
name,
inodes: vec![],
attrs: AttrMap::new(),
}
}
#[inline(always)]
pub fn attr<S: AsRef<str>>(&self, metadata: &BoxMetadata, key: S) -> Option<&[u8]> {
let key = metadata.attr_key(key.as_ref())?;
self.attrs.get(&key).map(|x| &**x)
}
#[inline(always)]
pub fn upcast(self) -> Record {
Record::Directory(self)
}
}
#[derive(Debug)]
pub struct FileRecord {
pub compression: Compression,
pub length: u64,
pub decompressed_length: u64,
pub data: NonZeroU64,
pub name: String,
pub attrs: AttrMap,
}
impl FileRecord {
#[inline(always)]
pub fn compression(&self) -> Compression {
self.compression
}
#[inline(always)]
pub fn attr<S: AsRef<str>>(&self, metadata: &BoxMetadata, key: S) -> Option<&[u8]> {
let key = metadata.attr_key(key.as_ref())?;
self.attrs.get(&key).map(|x| &**x)
}
#[inline(always)]
pub fn upcast(self) -> Record {
Record::File(self)
}
}