1
1
use std:: { cell:: RefCell , collections:: BTreeMap , ffi:: OsStr , path:: Path , rc:: Rc } ;
2
2
3
- use anyhow :: { bail , Context , Result } ;
3
+ use thiserror :: Error ;
4
4
5
5
use crate :: fsverity:: Sha256HashValue ;
6
6
@@ -47,6 +47,18 @@ pub enum Inode {
47
47
Leaf ( Rc < Leaf > ) ,
48
48
}
49
49
50
+ #[ derive( Error , Debug ) ]
51
+ pub enum ImageError {
52
+ #[ error( "Directory entry {0:?} does not exist" ) ]
53
+ NotFound ( Box < OsStr > ) ,
54
+ #[ error( "Directory entry {0:?} is not a subdirectory" ) ]
55
+ NotADirectory ( Box < OsStr > ) ,
56
+ #[ error( "Directory entry {0:?} is a directory" ) ]
57
+ IsADirectory ( Box < OsStr > ) ,
58
+ #[ error( "Directory entry {0:?} is not a regular file" ) ]
59
+ IsNotRegular ( Box < OsStr > ) ,
60
+ }
61
+
50
62
impl Inode {
51
63
pub fn stat ( & self ) -> & Stat {
52
64
match self {
@@ -64,11 +76,11 @@ impl Directory {
64
76
}
65
77
}
66
78
67
- pub fn recurse ( & mut self , name : impl AsRef < OsStr > ) -> Result < & mut Directory > {
79
+ pub fn recurse ( & mut self , name : impl AsRef < OsStr > ) -> Result < & mut Directory , ImageError > {
68
80
match self . entries . get_mut ( name. as_ref ( ) ) {
69
81
Some ( Inode :: Directory ( subdir) ) => Ok ( subdir) ,
70
- Some ( _) => bail ! ( "Parent directory is not a directory" ) ,
71
- None => bail ! ( "Unable to find parent directory {:?}" , name. as_ref( ) ) ,
82
+ Some ( _) => Err ( ImageError :: NotADirectory ( name . as_ref ( ) . into ( ) ) ) ,
83
+ None => Err ( ImageError :: NotFound ( name. as_ref ( ) . into ( ) ) ) ,
72
84
}
73
85
}
74
86
@@ -90,11 +102,11 @@ impl Directory {
90
102
self . entries . insert ( name. into ( ) , inode) ;
91
103
}
92
104
93
- pub fn get_for_link ( & self , name : & OsStr ) -> Result < Rc < Leaf > > {
105
+ pub fn get_for_link ( & self , name : & OsStr ) -> Result < Rc < Leaf > , ImageError > {
94
106
match self . entries . get ( name) {
95
107
Some ( Inode :: Leaf ( leaf) ) => Ok ( Rc :: clone ( leaf) ) ,
96
- Some ( Inode :: Directory ( ..) ) => bail ! ( "Cannot hardlink to directory" ) ,
97
- None => bail ! ( "Attempt to hardlink to non-existent file" ) ,
108
+ Some ( Inode :: Directory ( ..) ) => Err ( ImageError :: IsADirectory ( name . into ( ) ) ) ,
109
+ None => Err ( ImageError :: NotFound ( name . into ( ) ) ) ,
98
110
}
99
111
}
100
112
@@ -145,7 +157,7 @@ impl FileSystem {
145
157
}
146
158
}
147
159
148
- fn get_parent_dir < ' a > ( & ' a mut self , name : & Path ) -> Result < & ' a mut Directory > {
160
+ fn get_parent_dir < ' a > ( & ' a mut self , name : & Path ) -> Result < & ' a mut Directory , ImageError > {
149
161
let mut dir = & mut self . root ;
150
162
151
163
if let Some ( parent) = name. parent ( ) {
@@ -154,24 +166,22 @@ impl FileSystem {
154
166
// Path.parent() is really weird...
155
167
continue ;
156
168
}
157
- dir = dir
158
- . recurse ( segment)
159
- . with_context ( || format ! ( "Trying to insert item {:?}" , name) ) ?;
169
+ dir = dir. recurse ( segment) ?;
160
170
}
161
171
}
162
172
163
173
Ok ( dir)
164
174
}
165
175
166
- pub fn mkdir ( & mut self , name : & Path , stat : Stat ) -> Result < ( ) > {
176
+ pub fn mkdir ( & mut self , name : & Path , stat : Stat ) -> Result < ( ) , ImageError > {
167
177
if let Some ( filename) = name. file_name ( ) {
168
178
let dir = self . get_parent_dir ( name) ?;
169
179
dir. mkdir ( filename, stat) ;
170
180
}
171
181
Ok ( ( ) )
172
182
}
173
183
174
- pub fn insert_rc ( & mut self , name : & Path , leaf : Rc < Leaf > ) -> Result < ( ) > {
184
+ pub fn insert_rc ( & mut self , name : & Path , leaf : Rc < Leaf > ) -> Result < ( ) , ImageError > {
175
185
if let Some ( filename) = name. file_name ( ) {
176
186
let dir = self . get_parent_dir ( name) ?;
177
187
dir. insert ( filename, Inode :: Leaf ( leaf) ) ;
@@ -181,11 +191,11 @@ impl FileSystem {
181
191
}
182
192
}
183
193
184
- pub fn insert ( & mut self , name : & Path , leaf : Leaf ) -> Result < ( ) > {
194
+ pub fn insert ( & mut self , name : & Path , leaf : Leaf ) -> Result < ( ) , ImageError > {
185
195
self . insert_rc ( name, Rc :: new ( leaf) )
186
196
}
187
197
188
- fn get_for_link ( & mut self , name : & Path ) -> Result < Rc < Leaf > > {
198
+ fn get_for_link ( & mut self , name : & Path ) -> Result < Rc < Leaf > , ImageError > {
189
199
if let Some ( filename) = name. file_name ( ) {
190
200
let dir = self . get_parent_dir ( name) ?;
191
201
dir. get_for_link ( filename)
@@ -194,12 +204,12 @@ impl FileSystem {
194
204
}
195
205
}
196
206
197
- pub fn hardlink ( & mut self , name : & Path , target : & OsStr ) -> Result < ( ) > {
207
+ pub fn hardlink ( & mut self , name : & Path , target : & OsStr ) -> Result < ( ) , ImageError > {
198
208
let rc = self . get_for_link ( Path :: new ( target) ) ?;
199
209
self . insert_rc ( name, rc)
200
210
}
201
211
202
- pub fn remove ( & mut self , name : & Path ) -> Result < ( ) > {
212
+ pub fn remove ( & mut self , name : & Path ) -> Result < ( ) , ImageError > {
203
213
if let Some ( filename) = name. file_name ( ) {
204
214
let dir = self . get_parent_dir ( name) ?;
205
215
dir. remove ( filename) ;
0 commit comments