@@ -10,7 +10,7 @@ use std::convert::TryFrom;
10
10
use std:: path:: Path ;
11
11
12
12
#[ derive( thiserror:: Error , Debug ) ]
13
- pub enum Error {
13
+ pub enum Error < E : std :: error :: Error + ' static > {
14
14
#[ error( transparent) ]
15
15
Commit ( #[ from] file:: commit:: Error ) ,
16
16
#[ error( "commit at file position {pos} has invalid ID {id}" ) ]
@@ -26,24 +26,13 @@ pub enum Error {
26
26
#[ error( "commit {id} has invalid generation {generation}" ) ]
27
27
Generation { generation : u32 , id : owned:: Id } ,
28
28
#[ error( "checksum mismatch: expected {expected}, got {actual}" ) ]
29
- Mismatch { expected : owned:: Id , actual : owned:: Id } ,
29
+ Mismatch { actual : owned:: Id , expected : owned:: Id } ,
30
+ #[ error( "{0}" ) ]
31
+ Processor ( #[ source] E ) ,
30
32
#[ error( "commit {id} has invalid root tree ID {root_tree_id}" ) ]
31
33
RootTreeId { id : owned:: Id , root_tree_id : owned:: Id } ,
32
34
}
33
35
34
- // This is a separate type to let `traverse`'s caller use the same error type for its result and its
35
- // processor error type while also letting that error type contain file::verify::Error values.
36
- // Is there a better way? Should the caller's error type just use boxes to avoid recursive type
37
- // errors?
38
- #[ derive( thiserror:: Error , Debug ) ]
39
- pub enum EitherError < E1 : std:: error:: Error + ' static , E2 : std:: error:: Error + ' static > {
40
- #[ error( transparent) ]
41
- Internal ( #[ from] E1 ) ,
42
- // Why can't I use #[from] here? Boo!
43
- #[ error( "{0}" ) ]
44
- Processor ( #[ source] E2 ) ,
45
- }
46
-
47
36
#[ derive( Clone , Debug , Eq , PartialEq ) ]
48
37
#[ cfg_attr( feature = "serde1" , derive( serde:: Deserialize , serde:: Serialize ) ) ]
49
38
pub struct Outcome {
@@ -59,13 +48,14 @@ impl File {
59
48
borrowed:: Id :: try_from ( & self . data [ self . data . len ( ) - SHA1_SIZE ..] ) . expect ( "file to be large enough for a hash" )
60
49
}
61
50
62
- pub fn traverse < ' a , E , Processor > ( & ' a self , mut processor : Processor ) -> Result < Outcome , EitherError < Error , E > >
51
+ pub fn traverse < ' a , E , Processor > ( & ' a self , mut processor : Processor ) -> Result < Outcome , Error < E > >
63
52
where
64
53
E : std:: error:: Error + ' static ,
65
54
Processor : FnMut ( & file:: Commit < ' a > ) -> Result < ( ) , E > ,
66
55
{
67
- self . verify_checksum ( ) ?;
68
- verify_split_chain_filename_hash ( & self . path , self . checksum ( ) ) ?;
56
+ self . verify_checksum ( )
57
+ . map_err ( |( actual, expected) | Error :: Mismatch { actual, expected } ) ?;
58
+ verify_split_chain_filename_hash ( & self . path , self . checksum ( ) ) . map_err ( Error :: Filename ) ?;
69
59
70
60
// This probably belongs in borrowed::Id itself?
71
61
let null_id = borrowed:: Id :: from ( & [ 0u8 ; SHA1_SIZE ] ) ;
@@ -86,32 +76,28 @@ impl File {
86
76
return Err ( Error :: CommitId {
87
77
pos : commit. position ( ) ,
88
78
id : commit. id ( ) . into ( ) ,
89
- }
90
- . into ( ) ) ;
79
+ } ) ;
91
80
}
92
81
return Err ( Error :: CommitsOutOfOrder {
93
82
pos : commit. position ( ) ,
94
83
id : commit. id ( ) . into ( ) ,
95
84
predecessor_id : prev_id. into ( ) ,
96
- }
97
- . into ( ) ) ;
85
+ } ) ;
98
86
}
99
87
if commit. root_tree_id ( ) == null_id {
100
88
return Err ( Error :: RootTreeId {
101
89
id : commit. id ( ) . into ( ) ,
102
90
root_tree_id : commit. root_tree_id ( ) . into ( ) ,
103
- }
104
- . into ( ) ) ;
91
+ } ) ;
105
92
}
106
93
if commit. generation ( ) > GENERATION_NUMBER_MAX {
107
94
return Err ( Error :: Generation {
108
95
generation : commit. generation ( ) ,
109
96
id : commit. id ( ) . into ( ) ,
110
- }
111
- . into ( ) ) ;
97
+ } ) ;
112
98
}
113
99
114
- processor ( & commit) . map_err ( EitherError :: Processor ) ?;
100
+ processor ( & commit) . map_err ( Error :: Processor ) ?;
115
101
116
102
stats. max_generation = max ( stats. max_generation , commit. generation ( ) ) ;
117
103
stats. min_generation = min ( stats. min_generation , commit. generation ( ) ) ;
@@ -130,7 +116,7 @@ impl File {
130
116
Ok ( stats)
131
117
}
132
118
133
- pub fn verify_checksum ( & self ) -> Result < owned:: Id , Error > {
119
+ pub fn verify_checksum ( & self ) -> Result < owned:: Id , ( owned :: Id , owned :: Id ) > {
134
120
// TODO: Use/copy git_odb::hash::bytes_of_file.
135
121
let data_len_without_trailer = self . data . len ( ) - SHA1_SIZE ;
136
122
let mut hasher = git_features:: hash:: Sha1 :: default ( ) ;
@@ -141,27 +127,21 @@ impl File {
141
127
if actual. to_borrowed ( ) == expected {
142
128
Ok ( actual)
143
129
} else {
144
- Err ( Error :: Mismatch {
145
- actual,
146
- expected : expected. into ( ) ,
147
- } )
130
+ Err ( ( actual, expected. into ( ) ) )
148
131
}
149
132
}
150
133
}
151
134
152
135
/// If the given path's filename matches "graph-{hash}.graph", check that `hash` matches the
153
136
/// expected hash.
154
- fn verify_split_chain_filename_hash ( path : impl AsRef < Path > , expected : borrowed:: Id < ' _ > ) -> Result < ( ) , Error > {
137
+ fn verify_split_chain_filename_hash ( path : impl AsRef < Path > , expected : borrowed:: Id < ' _ > ) -> Result < ( ) , String > {
155
138
let path = path. as_ref ( ) ;
156
139
path. file_name ( )
157
140
. and_then ( |filename| filename. to_str ( ) )
158
141
. and_then ( |filename| filename. strip_suffix ( ".graph" ) )
159
142
. and_then ( |stem| stem. strip_prefix ( "graph-" ) )
160
143
. map_or ( Ok ( ( ) ) , |hex| match owned:: Id :: from_40_bytes_in_hex ( hex. as_bytes ( ) ) {
161
144
Ok ( actual) if actual. to_borrowed ( ) == expected => Ok ( ( ) ) ,
162
- _ => Err ( Error :: Filename ( format ! (
163
- "graph-{}.graph" ,
164
- expected. to_sha1_hex( ) . as_bstr( )
165
- ) ) ) ,
145
+ _ => Err ( format ! ( "graph-{}.graph" , expected. to_sha1_hex( ) . as_bstr( ) ) ) ,
166
146
} )
167
147
}
0 commit comments