1#![forbid(unsafe_code)]
2
3use serde::{Deserialize, Serialize};
13use std::fmt;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
17pub enum FsFileType {
18 RegularFile,
19 Directory,
20 Symlink,
21 CharDevice,
22 BlockDevice,
23 Fifo,
24 Socket,
25 Unknown,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
30pub struct FsTimestamp {
31 pub seconds: i64,
32 pub nanoseconds: u32,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct FsMetadata {
38 pub ino: u64,
39 pub file_type: FsFileType,
40 pub mode: u16,
41 pub uid: u32,
42 pub gid: u32,
43 pub size: u64,
44 pub links_count: u16,
45 pub atime: FsTimestamp,
46 pub mtime: FsTimestamp,
47 pub ctime: FsTimestamp,
48 pub crtime: FsTimestamp,
49 pub allocated: bool,
50}
51
52#[derive(Debug, Clone)]
54pub struct FsDirEntry {
55 pub inode: u64,
56 pub name: Vec<u8>,
57 pub file_type: FsFileType,
58}
59
60impl FsDirEntry {
61 pub fn name_str(&self) -> String {
62 String::from_utf8_lossy(&self.name).to_string()
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct FsDeletedInode {
69 pub ino: u64,
70 pub file_type: FsFileType,
71 pub size: u64,
72 pub dtime: u32,
73 pub recoverability: f64,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
79pub enum FsAllocation {
80 Deleted,
82 Orphan,
84}
85
86#[derive(Debug, Clone)]
93pub struct FsDeletedNode {
94 pub ino: u64,
96 pub name: Vec<u8>,
98 pub parent_ino: Option<u64>,
100 pub size: u64,
101 pub file_type: FsFileType,
102 pub allocation: FsAllocation,
103 pub record_id: u64,
105 pub atime: FsTimestamp,
106 pub mtime: FsTimestamp,
107 pub ctime: FsTimestamp,
108 pub crtime: FsTimestamp,
109}
110
111#[derive(Debug, Clone)]
113pub struct FsRecoveryResult {
114 pub ino: u64,
115 pub data: Vec<u8>,
116 pub expected_size: u64,
117 pub recovered_bytes: u64,
118 pub recovery_percentage: f64,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct FsTimelineEvent {
124 pub timestamp: FsTimestamp,
125 pub event_type: FsEventType,
126 pub inode: u64,
127 pub size: u64,
128 pub uid: u32,
129 pub gid: u32,
130}
131
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
134pub enum FsEventType {
135 Created,
136 Modified,
137 Accessed,
138 Changed,
139 Deleted,
140 Mounted,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct FsBlockRange {
146 pub start: u64,
147 pub length: u64,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct FsTransaction {
153 pub sequence: u64,
154 pub commit_seconds: u64,
155 pub commit_nanoseconds: u32,
156}
157
158#[derive(Debug)]
160pub enum FsError {
161 Io(std::io::Error),
162 NotSupported(String),
163 NotFound(String),
164 Corrupt(String),
165 Other(String),
166}
167
168impl fmt::Display for FsError {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 match self {
171 Self::Io(e) => write!(f, "I/O error: {e}"),
172 Self::NotSupported(msg) => write!(f, "not supported: {msg}"),
173 Self::NotFound(msg) => write!(f, "not found: {msg}"),
174 Self::Corrupt(msg) => write!(f, "corrupt: {msg}"),
175 Self::Other(msg) => write!(f, "{msg}"),
176 }
177 }
178}
179
180impl std::error::Error for FsError {
181 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
182 match self {
183 Self::Io(e) => Some(e),
184 _ => None,
185 }
186 }
187}
188
189impl From<std::io::Error> for FsError {
190 fn from(e: std::io::Error) -> Self {
191 Self::Io(e)
192 }
193}
194
195pub type FsResult<T> = std::result::Result<T, FsError>;
197
198pub fn not_supported(op: &str) -> FsError {
200 FsError::NotSupported(op.to_string())
201}
202
203pub fn not_found(what: &str) -> FsError {
205 FsError::NotFound(what.to_string())
206}