use std::fmt::Display;
use cid::Cid;
use crate::pb::{
self,
unixfs::{mod_Data::DataType, Data},
};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum FileType {
Raw = 0,
Directory = 1,
File = 2,
Metadata = 3,
Symlink = 4,
HAMTShard = 5,
}
impl Display for FileType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let file_type = match self {
FileType::Raw => "raw",
FileType::Directory => "directory",
FileType::File => "file",
FileType::Metadata => "metadata",
FileType::Symlink => "symlink",
FileType::HAMTShard => "hasmtshard",
};
write!(f, "{file_type}")
}
}
impl Default for FileType {
fn default() -> Self {
FileType::Raw
}
}
impl From<DataType> for FileType {
fn from(value: DataType) -> Self {
match value {
DataType::Raw => FileType::Raw,
DataType::Directory => FileType::Directory,
DataType::File => FileType::File,
DataType::Metadata => FileType::Metadata,
DataType::Symlink => FileType::Symlink,
DataType::HAMTShard => FileType::HAMTShard,
}
}
}
impl From<FileType> for DataType {
fn from(value: FileType) -> Self {
match value {
FileType::Raw => DataType::Raw,
FileType::Directory => DataType::Directory,
FileType::File => DataType::File,
FileType::Metadata => DataType::Metadata,
FileType::Symlink => DataType::Symlink,
FileType::HAMTShard => DataType::HAMTShard,
}
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct UnixTime {
pub seconds: i64,
pub fractional_nanoseconds: Option<u32>,
}
impl From<pb::unixfs::UnixTime> for UnixTime {
fn from(value: pb::unixfs::UnixTime) -> Self {
Self {
seconds: value.Seconds,
fractional_nanoseconds: value.FractionalNanoseconds,
}
}
}
impl From<UnixTime> for pb::unixfs::UnixTime {
fn from(value: UnixTime) -> Self {
Self {
Seconds: value.seconds,
FractionalNanoseconds: value.fractional_nanoseconds,
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct UnixFs {
pub cid: Option<Cid>,
pub mode: Option<u32>,
pub file_type: FileType,
pub fanout: Option<u64>,
pub block_sizes: Vec<u64>,
pub file_size: Option<u64>,
pub hash_type: Option<u64>,
pub links: Vec<Link>,
pub mtime: Option<UnixTime>,
pub file_name: Option<String>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct Link {
pub hash: Cid,
pub guess_type: FileType,
pub name: String,
pub tsize: u64,
}
impl Link {
pub fn new(hash: Cid, name: String, tsize: u64) -> Self {
Self {
hash,
name,
tsize,
guess_type: FileType::Raw,
}
}
#[inline(always)]
pub fn hash(&self) -> Cid {
self.hash
}
#[inline(always)]
pub fn name_ref(&self) -> &str {
&self.name
}
#[inline(always)]
pub fn tsize(&self) -> u64 {
self.tsize
}
#[inline(always)]
pub fn guess_type(&self) -> FileType {
self.guess_type
}
}
impl<'a> From<Data<'a>> for UnixFs {
fn from(value: Data<'a>) -> Self {
Self {
cid: None,
file_name: None,
file_type: value.Type.into(),
file_size: value.filesize,
block_sizes: value.blocksizes,
hash_type: value.hashType,
fanout: value.fanout,
mode: value.mode,
mtime: value.mtime.map(|t| t.into()),
links: Default::default(),
}
}
}
impl UnixFs {
pub fn new(cid: Cid) -> Self {
Self {
cid: Some(cid),
..Default::default()
}
}
pub fn new_directory() -> Self {
Self {
file_type: FileType::Directory,
..Default::default()
}
}
#[inline(always)]
pub fn add_link(&mut self, child: Link) -> usize {
let idx = self.links.len();
self.links.push(child);
idx
}
#[inline(always)]
pub fn links(&self) -> Vec<&Link> {
self.links.iter().collect()
}
#[inline(always)]
pub fn mtime(&self) -> Option<&UnixTime> {
self.mtime.as_ref()
}
#[inline(always)]
pub fn mode(&self) -> Option<u32> {
self.mode
}
#[inline(always)]
pub fn fanout(&self) -> Option<u64> {
self.fanout
}
#[inline(always)]
pub fn file_name(&self) -> Option<&str> {
self.file_name.as_deref()
}
#[inline(always)]
pub fn hash_type(&self) -> Option<u64> {
self.hash_type
}
#[inline(always)]
pub fn block_sizes(&self) -> Vec<u64> {
self.block_sizes.clone()
}
#[inline(always)]
pub fn file_size(&self) -> Option<u64> {
self.file_size
}
#[inline(always)]
pub fn file_type(&self) -> FileType {
self.file_type
}
#[inline(always)]
pub fn cid(&self) -> Option<Cid> {
self.cid
}
}