@@ -71,6 +71,16 @@ pub mod diff {
71
71
use git_object:: TreeRefIter ;
72
72
use git_odb:: FindExt ;
73
73
74
+ /// The error return by methods on the [diff platform][super::Platform].
75
+ #[ derive( Debug , thiserror:: Error ) ]
76
+ #[ allow( missing_docs) ]
77
+ pub enum Error {
78
+ #[ error( transparent) ]
79
+ Diff ( #[ from] git_diff:: tree:: changes:: Error ) ,
80
+ #[ error( "The user-provided callback failed" ) ]
81
+ ForEach ( #[ source] Box < dyn std:: error:: Error + Send + Sync + ' static > ) ,
82
+ }
83
+
74
84
/// Represents any possible change in order to turn one tree into another.
75
85
#[ derive( Debug , Clone , Copy ) ]
76
86
pub enum Event < ' repo , ' other_repo > {
@@ -121,35 +131,46 @@ pub mod diff {
121
131
122
132
/// Add the item to compare to.
123
133
impl < ' a , ' repo > Platform < ' a , ' repo > {
124
- pub fn to_obtain_tree < ' other_repo > (
134
+ /// Call `for_each` repeatedly with all changes that are needed to convert the source of the diff to the tree to `other`.
135
+ pub fn for_each_to_obtain_tree < ' other_repo , E > (
125
136
& mut self ,
126
137
other : & Tree < ' other_repo > ,
127
- for_each : impl FnMut ( Event < ' repo , ' other_repo > ) -> git_diff:: tree:: visit:: Action ,
128
- ) -> Result < ( ) , git_diff:: tree:: changes:: Error > {
138
+ for_each : impl FnMut ( Event < ' repo , ' other_repo > ) -> Result < git_diff:: tree:: visit:: Action , E > ,
139
+ ) -> Result < ( ) , Error >
140
+ where
141
+ E : std:: error:: Error + Sync + Send + ' static ,
142
+ {
129
143
let repo = self . lhs . repo ;
130
144
let mut delegate = Delegate {
131
145
repo : self . lhs . repo ,
132
146
other_repo : other. repo ,
133
147
visit : for_each,
148
+ err : None ,
134
149
} ;
135
150
git_diff:: tree:: Changes :: from ( TreeRefIter :: from_bytes ( & self . lhs . data ) ) . needed_to_obtain (
136
151
TreeRefIter :: from_bytes ( & other. data ) ,
137
152
& mut self . state ,
138
153
|oid, buf| repo. objects . find_tree_iter ( oid, buf) ,
139
154
& mut delegate,
140
- )
155
+ ) ?;
156
+ match delegate. err {
157
+ Some ( err) => Err ( Error :: ForEach ( Box :: new ( err) ) ) ,
158
+ None => Ok ( ( ) ) ,
159
+ }
141
160
}
142
161
}
143
162
144
- struct Delegate < ' repo , ' other_repo , VisitFn > {
163
+ struct Delegate < ' repo , ' other_repo , VisitFn , E > {
145
164
repo : & ' repo Repository ,
146
165
other_repo : & ' other_repo Repository ,
147
166
visit : VisitFn ,
167
+ err : Option < E > ,
148
168
}
149
169
150
- impl < ' repo , ' other_repo , VisitFn > git_diff:: tree:: Visit for Delegate < ' repo , ' other_repo , VisitFn >
170
+ impl < ' repo , ' other_repo , VisitFn , E > git_diff:: tree:: Visit for Delegate < ' repo , ' other_repo , VisitFn , E >
151
171
where
152
- VisitFn : FnMut ( Event < ' repo , ' other_repo > ) -> git_diff:: tree:: visit:: Action ,
172
+ VisitFn : FnMut ( Event < ' repo , ' other_repo > ) -> Result < git_diff:: tree:: visit:: Action , E > ,
173
+ E : std:: error:: Error + Sync + Send + ' static ,
153
174
{
154
175
fn pop_front_tracked_path_and_set_current ( & mut self ) { }
155
176
@@ -184,7 +205,13 @@ pub mod diff {
184
205
id : oid. attach ( self . other_repo ) ,
185
206
} ,
186
207
} ;
187
- ( self . visit ) ( event)
208
+ match ( self . visit ) ( event) {
209
+ Ok ( action) => action,
210
+ Err ( err) => {
211
+ self . err = Some ( err) ;
212
+ git_diff:: tree:: visit:: Action :: Cancel
213
+ }
214
+ }
188
215
}
189
216
}
190
217
}
0 commit comments