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}