Unified · Split
| @@ -1,15 +1,4 @@ | ||
| 1 | 1 | use crate::{data, pack}; |
| 2 | −use git_hash::ObjectId; | |
| 3 | − | |
| 4 | −/// The error returned by various [`find_*`][Find] trait methods. | |
| 5 | −#[derive(Debug, thiserror::Error)] | |
| 6 | −#[allow(missing_docs)] | |
| 7 | −pub enum Error<T: std::error::Error + 'static> { | |
| 8 | − #[error(transparent)] | |
| 9 | − Find(T), | |
| 10 | − #[error("An object with id {} could not be found", .oid)] | |
| 11 | − NotFound { oid: ObjectId }, | |
| 12 | −} | |
| 13 | 2 | |
| 14 | 3 | /// Describe how object can be located in an object store |
| 15 | 4 | /// |
| @@ -36,21 +25,6 @@ pub trait Find { · 20 unmodified lines | ||
| 36 | 25 | pack_cache: &mut impl crate::pack::cache::DecodeEntry, |
| 37 | 26 | ) -> Result<Option<data::Object<'a>>, Self::Error>; |
| 38 | 27 | |
| 39 | − /// Like [`find(…)`][Self::find()], but degenerates the `Result<Option<_>>` into a single `Result` making a non-existing object an error. | |
| 40 | − fn find_existing<'a>( | |
| 41 | − &self, | |
| 42 | − id: impl AsRef<git_hash::oid>, | |
| 43 | − buffer: &'a mut Vec<u8>, | |
| 44 | − pack_cache: &mut impl crate::pack::cache::DecodeEntry, | |
| 45 | − ) -> Result<data::Object<'a>, Error<Self::Error>> { | |
| 46 | − let id = id.as_ref(); | |
| 47 | − self.find(id, buffer, pack_cache) | |
| 48 | − .map_err(|err| Error::Find(err))? | |
| 49 | − .ok_or_else(|| Error::NotFound { | |
| 50 | − oid: id.as_ref().to_owned(), | |
| 51 | − }) | |
| 52 | − } | |
| 53 | − | |
| 54 | 28 | /// Return the [`PackEntry`] for `object` if it is backed by a pack. |
| 55 | 29 | /// |
| 56 | 30 | /// Note that this is only in the interest of avoiding duplicate work during pack generation |
| @@ -63,6 +37,46 @@ pub trait Find { · 6 unmodified lines | ||
| 63 | 37 | fn pack_entry(&self, object: &data::Object<'_>) -> Option<PackEntry<'_>>; |
| 64 | 38 | } |
| 65 | 39 | |
| 40 | +mod ext { | |
| 41 | + use crate::{data, find::find_existing}; | |
| 42 | + | |
| 43 | + /// An extension trait with convenience functions. | |
| 44 | + pub trait FindExt: super::Find { | |
| 45 | + /// Like [`find(…)`][Self::find()], but degenerates the `Result<Option<_>>` into a single `Result` making a non-existing object an error. | |
| 46 | + fn find_existing<'a>( | |
| 47 | + &self, | |
| 48 | + id: impl AsRef<git_hash::oid>, | |
| 49 | + buffer: &'a mut Vec<u8>, | |
| 50 | + pack_cache: &mut impl crate::pack::cache::DecodeEntry, | |
| 51 | + ) -> Result<data::Object<'a>, find_existing::Error<Self::Error>> { | |
| 52 | + let id = id.as_ref(); | |
| 53 | + self.find(id, buffer, pack_cache) | |
| 54 | + .map_err(|err| find_existing::Error::Find(err))? | |
| 55 | + .ok_or_else(|| find_existing::Error::NotFound { | |
| 56 | + oid: id.as_ref().to_owned(), | |
| 57 | + }) | |
| 58 | + } | |
| 59 | + } | |
| 60 | + | |
| 61 | + impl<T: super::Find> FindExt for T {} | |
| 62 | +} | |
| 63 | +pub use ext::FindExt; | |
| 64 | + | |
| 65 | +/// | |
| 66 | +pub mod find_existing { | |
| 67 | + use git_hash::ObjectId; | |
| 68 | + | |
| 69 | + /// The error returned by various [`find_*`][crate::FindExt] trait methods. | |
| 70 | + #[derive(Debug, thiserror::Error)] | |
| 71 | + #[allow(missing_docs)] | |
| 72 | + pub enum Error<T: std::error::Error + 'static> { | |
| 73 | + #[error(transparent)] | |
| 74 | + Find(T), | |
| 75 | + #[error("An object with id {} could not be found", .oid)] | |
| 76 | + NotFound { oid: ObjectId }, | |
| 77 | + } | |
| 78 | +} | |
| 79 | + | |
| 66 | 80 | #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] |
| 67 | 81 | #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] |
| 68 | 82 | #[allow(missing_docs)] // TODO: docs |