gix_odb/
traits.rs

1use crate::find;
2
3/// A way to obtain object properties without fully decoding it.
4pub trait Header {
5    /// Try to read the header of the object associated with `id` or return `None` if it could not be found.
6    fn try_header(&self, id: &gix_hash::oid) -> Result<Option<find::Header>, gix_object::find::Error>;
7}
8
9mod _impls {
10    use std::{ops::Deref, rc::Rc, sync::Arc};
11
12    use gix_hash::oid;
13
14    use crate::find::Header;
15
16    impl<T> crate::Header for &T
17    where
18        T: crate::Header,
19    {
20        fn try_header(&self, id: &oid) -> Result<Option<Header>, gix_object::find::Error> {
21            (*self).try_header(id)
22        }
23    }
24
25    impl<T> crate::Header for Rc<T>
26    where
27        T: crate::Header,
28    {
29        fn try_header(&self, id: &oid) -> Result<Option<Header>, gix_object::find::Error> {
30            self.deref().try_header(id)
31        }
32    }
33
34    impl<T> crate::Header for Arc<T>
35    where
36        T: crate::Header,
37    {
38        fn try_header(&self, id: &oid) -> Result<Option<Header>, gix_object::find::Error> {
39            self.deref().try_header(id)
40        }
41    }
42}
43
44mod ext {
45    use crate::find;
46    /// An extension trait with convenience functions.
47    pub trait HeaderExt: super::Header {
48        /// Like [`try_header(…)`][super::Header::try_header()], but flattens the `Result<Option<_>>` into a single `Result` making a non-existing object an error.
49        fn header(&self, id: impl AsRef<gix_hash::oid>) -> Result<find::Header, gix_object::find::existing::Error> {
50            let id = id.as_ref();
51            self.try_header(id)
52                .map_err(gix_object::find::existing::Error::Find)?
53                .ok_or_else(|| gix_object::find::existing::Error::NotFound { oid: id.to_owned() })
54        }
55    }
56
57    impl<T: super::Header> HeaderExt for T {}
58}
59pub use ext::HeaderExt;