@@ -392,7 +392,28 @@ pub trait OdbBackend: Sized {
392
392
unimplemented ! ( "OdbBackend::open_write_stream" )
393
393
}
394
394
395
- // TODO: fn foreach()
395
+ /// Iterates through all objects this backend knows of.
396
+ ///
397
+ /// Corresponds to the `foreach` function of [`git_odb_backend`].
398
+ /// Requires that [`SupportedOperations::FOREACH`] is present in the value returned from
399
+ /// [`supported_operations`].
400
+ ///
401
+ /// The default implementation of this method panics.
402
+ ///
403
+ /// # Implementation notes
404
+ ///
405
+ /// For each object in this backend, `callback` should be invoked with the object's Oid once.
406
+ /// See [`ForeachCallback::invoke`].
407
+ ///
408
+ /// # Errors
409
+ ///
410
+ /// If the callback returns an error, the backend SHOULD propagate that error instead of
411
+ /// continuing iteration.
412
+ ///
413
+ /// See [`OdbBackend`] for more recommendations.
414
+ fn foreach ( & mut self , ctx : & OdbBackendContext , callback : ForeachCallback ) -> Result < ( ) , Error > {
415
+ unimplemented ! ( "OdbBackend::foreach" )
416
+ }
396
417
}
397
418
398
419
bitflags ! {
@@ -827,6 +848,37 @@ impl<B: OdbBackend> OdbWriteStream<B> for Infallible {
827
848
}
828
849
}
829
850
851
+ /// Callback used in calls to [`OdbBackend::foreach`].
852
+ ///
853
+ /// A wrapper for [`git_odb_foreach_cb`](raw::git_odb_foreach_cb).
854
+ pub struct ForeachCallback {
855
+ callback : raw:: git_odb_foreach_cb ,
856
+ payload : * mut libc:: c_void ,
857
+ }
858
+ impl ForeachCallback {
859
+ /// Invokes this callback.
860
+ ///
861
+ /// # Arguments
862
+ ///
863
+ /// `oid` should be the ID of the object that was iterated over.
864
+ ///
865
+ /// # Return value
866
+ ///
867
+ /// Returns `Ok(())` if the callback returns 0.
868
+ /// Returns an error if the callback returns a non-zero integer.
869
+ pub fn invoke ( & mut self , oid : & Oid ) -> Result < ( ) , Error > {
870
+ let code = match self . callback {
871
+ Some ( callback) => callback ( oid. raw ( ) , self . payload ) ,
872
+ None => return Ok ( ( ) ) , // maybe this should be an error
873
+ } ;
874
+ if code != 0 {
875
+ Err ( Error :: last_error ( code) )
876
+ } else {
877
+ Ok ( ( ) )
878
+ }
879
+ }
880
+ }
881
+
830
882
/// Context struct passed to [`OdbReadStream`] and [`OdbWriteStream`]'s methods.
831
883
pub struct OdbStreamContext < B : OdbBackend > {
832
884
backend_ptr : ptr:: NonNull < Backend < B > > ,
@@ -922,6 +974,7 @@ impl<'a, B: OdbBackend> CustomOdbBackend<'a, B> {
922
974
op_if ! ( exists if EXISTS ) ;
923
975
op_if ! ( exists_prefix if EXISTS_PREFIX ) ;
924
976
op_if ! ( refresh if REFRESH ) ;
977
+ op_if ! ( foreach if FOREACH ) ;
925
978
op_if ! ( writepack if WRITE_PACK ) ;
926
979
op_if ! ( writemidx if WRITE_MULTIPACK_INDEX ) ;
927
980
op_if ! ( freshen if FRESHEN ) ;
@@ -1187,6 +1240,23 @@ impl<B: OdbBackend> Backend<B> {
1187
1240
raw:: GIT_OK
1188
1241
}
1189
1242
1243
+ extern "C" fn foreach (
1244
+ backend_ptr : * mut raw:: git_odb_backend ,
1245
+ foreach_cb : raw:: git_odb_foreach_cb ,
1246
+ foreach_cb_payload : * mut libc:: c_void ,
1247
+ ) -> libc:: c_int {
1248
+ let backend = unsafe { backend_ptr. cast :: < Self > ( ) . as_mut ( ) . unwrap ( ) } ;
1249
+ let context = OdbBackendContext { backend_ptr } ;
1250
+ let callback = ForeachCallback {
1251
+ callback : foreach_cb,
1252
+ payload : foreach_cb_payload,
1253
+ } ;
1254
+ if let Err ( e) = backend. inner . foreach ( & context, callback) {
1255
+ return unsafe { e. raw_set_git_error ( ) } ;
1256
+ }
1257
+ raw:: GIT_OK
1258
+ }
1259
+
1190
1260
extern "C" fn writepack (
1191
1261
out_writepack_ptr : * mut * mut raw:: git_odb_writepack ,
1192
1262
backend_ptr : * mut raw:: git_odb_backend ,
0 commit comments