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