Skip to content

Commit d9218e5

Browse files
committed
feat: FindExt now supports empty trees and empty blobs natively.
1 parent 22a6188 commit d9218e5

File tree

1 file changed

+62
-2
lines changed

1 file changed

+62
-2
lines changed

gix-object/src/traits.rs

+62-2
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,70 @@ mod find {
287287
.ok_or_else(|| find::existing::Error::NotFound { oid: id.to_owned() })
288288
}
289289

290+
/// Like [`find(…)`][Self::find()], but flattens the `Result<Option<_>>` into a single `Result` making a non-existing object an error
291+
/// while returning the desired object type.
292+
fn find_blob<'a>(
293+
&self,
294+
id: &gix_hash::oid,
295+
buffer: &'a mut Vec<u8>,
296+
) -> Result<BlobRef<'a>, find::existing_object::Error> {
297+
if id == gix_hash::ObjectId::empty_blob(id.kind()) {
298+
return Ok(BlobRef { data: &[] });
299+
}
300+
self.try_find(id, buffer)
301+
.map_err(find::existing_object::Error::Find)?
302+
.ok_or_else(|| find::existing_object::Error::NotFound {
303+
oid: id.as_ref().to_owned(),
304+
})
305+
.and_then(|o| {
306+
o.decode().map_err(|err| find::existing_object::Error::Decode {
307+
source: err,
308+
oid: id.as_ref().to_owned(),
309+
})
310+
})
311+
.and_then(|o| match o {
312+
ObjectRef::Blob(o) => Ok(o),
313+
o => Err(find::existing_object::Error::ObjectKind {
314+
oid: id.as_ref().to_owned(),
315+
actual: o.kind(),
316+
expected: Kind::Blob,
317+
}),
318+
})
319+
}
320+
321+
/// Like [`find(…)`][Self::find()], but flattens the `Result<Option<_>>` into a single `Result` making a non-existing object an error
322+
/// while returning the desired object type.
323+
fn find_tree<'a>(
324+
&self,
325+
id: &gix_hash::oid,
326+
buffer: &'a mut Vec<u8>,
327+
) -> Result<TreeRef<'a>, find::existing_object::Error> {
328+
if id == gix_hash::ObjectId::empty_tree(id.kind()) {
329+
return Ok(TreeRef { entries: Vec::new() });
330+
}
331+
self.try_find(id, buffer)
332+
.map_err(find::existing_object::Error::Find)?
333+
.ok_or_else(|| find::existing_object::Error::NotFound {
334+
oid: id.as_ref().to_owned(),
335+
})
336+
.and_then(|o| {
337+
o.decode().map_err(|err| find::existing_object::Error::Decode {
338+
source: err,
339+
oid: id.as_ref().to_owned(),
340+
})
341+
})
342+
.and_then(|o| match o {
343+
ObjectRef::Tree(o) => Ok(o),
344+
o => Err(find::existing_object::Error::ObjectKind {
345+
oid: id.as_ref().to_owned(),
346+
actual: o.kind(),
347+
expected: Kind::Tree,
348+
}),
349+
})
350+
}
351+
290352
make_obj_lookup!(find_commit, ObjectRef::Commit, Kind::Commit, CommitRef<'a>);
291-
make_obj_lookup!(find_tree, ObjectRef::Tree, Kind::Tree, TreeRef<'a>);
292353
make_obj_lookup!(find_tag, ObjectRef::Tag, Kind::Tag, TagRef<'a>);
293-
make_obj_lookup!(find_blob, ObjectRef::Blob, Kind::Blob, BlobRef<'a>);
294354
make_iter_lookup!(find_commit_iter, Kind::Commit, CommitRefIter<'a>, try_into_commit_iter);
295355
make_iter_lookup!(find_tree_iter, Kind::Tree, TreeRefIter<'a>, try_into_tree_iter);
296356
make_iter_lookup!(find_tag_iter, Kind::Tag, TagRefIter<'a>, try_into_tag_iter);

0 commit comments

Comments
 (0)