blockless_car/
unixfs.rs

1use std::fmt::Display;
2
3use cid::Cid;
4
5use crate::pb::{
6    self,
7    unixfs::{mod_Data::DataType, Data},
8};
9
10#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
11pub enum FileType {
12    #[default]
13    Raw = 0,
14    Directory = 1,
15    File = 2,
16    Metadata = 3,
17    Symlink = 4,
18    HAMTShard = 5,
19}
20
21impl Display for FileType {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        let file_type = match self {
24            FileType::Raw => "raw",
25            FileType::Directory => "directory",
26            FileType::File => "file",
27            FileType::Metadata => "metadata",
28            FileType::Symlink => "symlink",
29            FileType::HAMTShard => "hasmtshard",
30        };
31        write!(f, "{file_type}")
32    }
33}
34
35impl From<DataType> for FileType {
36    fn from(value: DataType) -> Self {
37        match value {
38            DataType::Raw => FileType::Raw,
39            DataType::Directory => FileType::Directory,
40            DataType::File => FileType::File,
41            DataType::Metadata => FileType::Metadata,
42            DataType::Symlink => FileType::Symlink,
43            DataType::HAMTShard => FileType::HAMTShard,
44        }
45    }
46}
47
48impl From<FileType> for DataType {
49    fn from(value: FileType) -> Self {
50        match value {
51            FileType::Raw => DataType::Raw,
52            FileType::Directory => DataType::Directory,
53            FileType::File => DataType::File,
54            FileType::Metadata => DataType::Metadata,
55            FileType::Symlink => DataType::Symlink,
56            FileType::HAMTShard => DataType::HAMTShard,
57        }
58    }
59}
60
61#[allow(clippy::derive_partial_eq_without_eq)]
62#[derive(Debug, Default, PartialEq, Eq, Clone)]
63pub struct UnixTime {
64    pub seconds: i64,
65    pub fractional_nanoseconds: Option<u32>,
66}
67
68impl From<pb::unixfs::UnixTime> for UnixTime {
69    fn from(value: pb::unixfs::UnixTime) -> Self {
70        Self {
71            seconds: value.Seconds,
72            fractional_nanoseconds: value.FractionalNanoseconds,
73        }
74    }
75}
76
77impl From<UnixTime> for pb::unixfs::UnixTime {
78    fn from(value: UnixTime) -> Self {
79        Self {
80            Seconds: value.seconds,
81            FractionalNanoseconds: value.fractional_nanoseconds,
82        }
83    }
84}
85
86#[derive(Debug, PartialEq, Eq, Clone, Default)]
87pub struct UnixFs {
88    pub cid: Option<Cid>,
89    pub mode: Option<u32>,
90    pub file_type: FileType,
91    pub fanout: Option<u64>,
92    pub block_sizes: Vec<u64>,
93    pub file_size: Option<u64>,
94    pub hash_type: Option<u64>,
95    pub links: Vec<Link>,
96    pub mtime: Option<UnixTime>,
97    pub file_name: Option<String>,
98}
99
100#[derive(Debug, PartialEq, Eq, Clone, Default)]
101pub struct Link {
102    pub hash: Cid,
103    pub file_type: FileType,
104    pub name: String,
105    pub tsize: u64,
106}
107
108impl<'a> From<Data<'a>> for UnixFs {
109    fn from(value: Data<'a>) -> Self {
110        Self {
111            cid: None,
112            file_name: None,
113            file_type: value.Type.into(),
114            file_size: value.filesize,
115            block_sizes: value.blocksizes,
116            hash_type: value.hashType,
117            fanout: value.fanout,
118            mode: value.mode,
119            mtime: value.mtime.map(|t| t.into()),
120            links: Default::default(),
121        }
122    }
123}
124
125impl UnixFs {
126    pub fn new(cid: Cid) -> Self {
127        Self {
128            cid: Some(cid),
129            ..Default::default()
130        }
131    }
132
133    pub fn new_directory() -> Self {
134        Self {
135            file_type: FileType::Directory,
136            ..Default::default()
137        }
138    }
139
140    #[inline(always)]
141    pub fn add_link(&mut self, child: Link) -> usize {
142        let idx = self.links.len();
143        self.links.push(child);
144        idx
145    }
146
147    #[inline(always)]
148    pub fn links(&self) -> Vec<&Link> {
149        self.links.iter().collect()
150    }
151
152    #[inline(always)]
153    pub fn mtime(&self) -> Option<&UnixTime> {
154        self.mtime.as_ref()
155    }
156
157    #[inline(always)]
158    pub fn mode(&self) -> Option<u32> {
159        self.mode
160    }
161
162    #[inline(always)]
163    pub fn fanout(&self) -> Option<u64> {
164        self.fanout
165    }
166
167    #[inline(always)]
168    pub fn file_name(&self) -> Option<&str> {
169        self.file_name.as_deref()
170    }
171
172    #[inline(always)]
173    pub fn hash_type(&self) -> Option<u64> {
174        self.hash_type
175    }
176
177    #[inline(always)]
178    pub fn block_sizes(&self) -> Vec<u64> {
179        self.block_sizes.clone()
180    }
181
182    #[inline(always)]
183    pub fn file_size(&self) -> Option<u64> {
184        self.file_size
185    }
186
187    #[inline(always)]
188    pub fn file_type(&self) -> FileType {
189        self.file_type
190    }
191
192    #[inline(always)]
193    pub fn cid(&self) -> Option<Cid> {
194        self.cid
195    }
196}