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}