Skip to content

Commit 7e8e15a

Browse files
committed
feat: Add OdbBackend::exists_prefix
1 parent 5244f6b commit 7e8e15a

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

src/odb_backend.rs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub trait OdbBackend {
7878
/// Only the first `oid_prefix_len * 4` bits of `oid_prefix` are set.
7979
/// The remaining `(GIT_OID_SHA1_HEXSIZE - oid_prefix_len) * 4` bits are set to 0.
8080
///
81-
/// If an implementation returns `Ok(())`, `oid`, `data`, and `object_type` SHOULD be set to the
81+
/// If an implementation returns `Ok(())`, `oid`, `data`, and `object_type` MUST be set to the
8282
/// full object ID, the object type, and the contents of the object respectively.
8383
///
8484
/// [`OdbBackendAllocation`]s SHOULD be created using `ctx` (see
@@ -112,7 +112,7 @@ pub trait OdbBackend {
112112
///
113113
/// # Implementation notes
114114
///
115-
/// If an implementation returns `Ok(())`, `length` and `object_type` SHOULD be set to the
115+
/// If an implementation returns `Ok(())`, `length` and `object_type` MUST be set to the
116116
/// length of the object's contents and the object type respectively.
117117
///
118118
/// # Errors
@@ -155,6 +155,36 @@ pub trait OdbBackend {
155155
unimplemented!("OdbBackend::exists")
156156
}
157157

158+
/// Check if an object exists based on a prefix of its [`Oid`].
159+
///
160+
/// Corresponds to the `exists_prefix` function of [`git_odb_backend`].
161+
/// Requires that [`SupportedOperations::EXISTS_PREFIX`] is present in the value returned from
162+
/// [`supported_operations`] to expose it to libgit2.
163+
///
164+
/// The default implementation of this method panics.
165+
///
166+
/// # Implementation notes
167+
///
168+
/// Only the first `oid_prefix_len * 4` bits of `oid_prefix` are set.
169+
/// The remaining `(GIT_OID_SHA1_HEXSIZE - oid_prefix_len) * 4` bits are set to 0.
170+
///
171+
/// If an implementation returns `Ok(oid)`, `oid` SHOULD be the full Oid of the object.
172+
///
173+
/// # Errors
174+
///
175+
/// See [`OdbBackend::exists`].
176+
///
177+
/// [`git_odb_backend`]: raw::git_odb_backend
178+
/// [`supported_operations`]: Self::supported_operations
179+
fn exists_prefix(
180+
&mut self,
181+
ctx: &OdbBackendContext,
182+
oid_prefix: Oid,
183+
oid_prefix_length: usize,
184+
) -> Result<Oid, Error> {
185+
unimplemented!("OdbBackend::exists_prefix")
186+
}
187+
158188
// TODO: fn write()
159189
// TODO: fn writestream()
160190
// TODO: fn readstream()
@@ -351,6 +381,7 @@ impl<'a, B: OdbBackend> CustomOdbBackend<'a, B> {
351381
op_if!(read_prefix if READ_PREFIX);
352382
op_if!(read_header if READ_HEADER);
353383
op_if!(exists if EXISTS);
384+
op_if!(exists_prefix if EXISTS_PREFIX);
354385

355386
backend.free = Some(Backend::<B>::free);
356387
}
@@ -480,6 +511,24 @@ impl<B: OdbBackend> Backend<B> {
480511
0
481512
}
482513
}
514+
515+
extern "C" fn exists_prefix(
516+
oid_ptr: *mut raw::git_oid,
517+
backend_ptr: *mut raw::git_odb_backend,
518+
oid_prefix_ptr: *const raw::git_oid,
519+
oid_prefix_len: size_t
520+
) -> c_int {
521+
let backend = unsafe { backend_ptr.cast::<Self>().as_mut().unwrap() };
522+
let oid_prefix = unsafe { Oid::from_raw(oid_prefix_ptr) };
523+
let oid = unsafe { oid_ptr.cast::<Oid>().as_mut().unwrap() };
524+
525+
let context = OdbBackendContext { backend_ptr };
526+
*oid = match backend.inner.exists_prefix(&context, oid_prefix, oid_prefix_len) {
527+
Err(e) => return unsafe { e.raw_set_git_error() },
528+
Ok(x) => x,
529+
};
530+
raw::GIT_OK
531+
}
483532

484533
extern "C" fn free(backend: *mut raw::git_odb_backend) {
485534
let inner = unsafe { Box::from_raw(backend.cast::<Self>()) };

0 commit comments

Comments
 (0)