| @@ -71,6 +71,17 @@ mod find { · 70 unmodified lines |
| 71 | ) -> Result<Option<crate::Data<'a>>, find::Error>; | 71 | ) -> Result<Option<crate::Data<'a>>, find::Error>; |
| 72 | } | 72 | } |
| 73 | | 73 | |
| | 74 | /// Find the header of an object in the object store. |
| | 75 | pub trait Header { |
| | 76 | /// Find the header of the object matching `id` in the database. |
| | 77 | /// |
| | 78 | /// Returns `Some` header if it was present, or the error that occurred during lookup. |
| | 79 | fn try_header(&self, id: &gix_hash::oid) -> Result<Option<crate::Header>, find::Error>; |
| | 80 | } |
| | 81 | |
| | 82 | /// A combination of [`Find`] and [`Header`] traits to help with `dyn` trait objects. |
| | 83 | pub trait FindObjectOrHeader: Find + Header {} |
| | 84 | |
| 74 | mod _impls { | 85 | mod _impls { |
| 75 | use std::{ops::Deref, rc::Rc, sync::Arc}; | 86 | use std::{ops::Deref, rc::Rc, sync::Arc}; |
| 76 | | 87 | |
| @@ -86,6 +97,8 @@ mod find { · 9 unmodified lines |
| 86 | } | 97 | } |
| 87 | } | 98 | } |
| 88 | | 99 | |
| | 100 | impl<T> crate::FindObjectOrHeader for T where T: crate::Find + crate::FindHeader {} |
| | 101 | |
| 89 | impl<T> crate::Find for &T | 102 | impl<T> crate::Find for &T |
| 90 | where | 103 | where |
| 91 | T: crate::Find, | 104 | T: crate::Find, |
| @@ -95,6 +108,15 @@ mod find { · 3 unmodified lines |
| 95 | } | 108 | } |
| 96 | } | 109 | } |
| 97 | | 110 | |
| | 111 | impl<T> crate::FindHeader for &T |
| | 112 | where |
| | 113 | T: crate::FindHeader, |
| | 114 | { |
| | 115 | fn try_header(&self, id: &gix_hash::oid) -> Result<Option<crate::Header>, crate::find::Error> { |
| | 116 | (*self).try_header(id) |
| | 117 | } |
| | 118 | } |
| | 119 | |
| 98 | impl<T> crate::Exists for Box<T> | 120 | impl<T> crate::Exists for Box<T> |
| 99 | where | 121 | where |
| 100 | T: crate::Exists, | 122 | T: crate::Exists, |
| @@ -122,6 +144,15 @@ mod find { · 21 unmodified lines |
| 122 | } | 144 | } |
| 123 | } | 145 | } |
| 124 | | 146 | |
| | 147 | impl<T> crate::FindHeader for Rc<T> |
| | 148 | where |
| | 149 | T: crate::FindHeader, |
| | 150 | { |
| | 151 | fn try_header(&self, id: &gix_hash::oid) -> Result<Option<crate::Header>, crate::find::Error> { |
| | 152 | self.deref().try_header(id) |
| | 153 | } |
| | 154 | } |
| | 155 | |
| 125 | impl<T> crate::Find for Box<T> | 156 | impl<T> crate::Find for Box<T> |
| 126 | where | 157 | where |
| 127 | T: crate::Find, | 158 | T: crate::Find, |
| @@ -131,6 +162,15 @@ mod find { · 3 unmodified lines |
| 131 | } | 162 | } |
| 132 | } | 163 | } |
| 133 | | 164 | |
| | 165 | impl<T> crate::FindHeader for Box<T> |
| | 166 | where |
| | 167 | T: crate::FindHeader, |
| | 168 | { |
| | 169 | fn try_header(&self, id: &gix_hash::oid) -> Result<Option<crate::Header>, crate::find::Error> { |
| | 170 | self.deref().try_header(id) |
| | 171 | } |
| | 172 | } |
| | 173 | |
| 134 | impl<T> crate::Exists for Arc<T> | 174 | impl<T> crate::Exists for Arc<T> |
| 135 | where | 175 | where |
| 136 | T: crate::Exists, | 176 | T: crate::Exists, |
| @@ -148,6 +188,15 @@ mod find { · 11 unmodified lines |
| 148 | self.deref().try_find(id, buffer) | 188 | self.deref().try_find(id, buffer) |
| 149 | } | 189 | } |
| 150 | } | 190 | } |
| | 191 | |
| | 192 | impl<T> crate::FindHeader for Arc<T> |
| | 193 | where |
| | 194 | T: crate::FindHeader, |
| | 195 | { |
| | 196 | fn try_header(&self, id: &gix_hash::oid) -> Result<Option<crate::Header>, crate::find::Error> { |
| | 197 | self.deref().try_header(id) |
| | 198 | } |
| | 199 | } |
| 151 | } | 200 | } |
| 152 | | 201 | |
| 153 | mod ext { | 202 | mod ext { |
| @@ -214,9 +263,19 @@ mod find { · 60 unmodified lines |
| 214 | }; | 263 | }; |
| 215 | } | 264 | } |
| 216 | | 265 | |
| | 266 | /// An extension trait with convenience functions. |
| | 267 | pub trait HeaderExt: super::Header { |
| | 268 | /// Like [`try_header(…)`](super::Header::try_header()), but flattens the `Result<Option<_>>` into a single `Result` making a non-existing header an error. |
| | 269 | fn header(&self, id: &gix_hash::oid) -> Result<crate::Header, find::existing::Error> { |
| | 270 | self.try_header(id) |
| | 271 | .map_err(find::existing::Error::Find)? |
| | 272 | .ok_or_else(|| find::existing::Error::NotFound { oid: id.to_owned() }) |
| | 273 | } |
| | 274 | } |
| | 275 | |
| 217 | /// An extension trait with convenience functions. | 276 | /// An extension trait with convenience functions. |
| 218 | pub trait FindExt: super::Find { | 277 | pub trait FindExt: super::Find { |
| 219 | /// Like [`try_find(…)`][super::Find::try_find()], but flattens the `Result<Option<_>>` into a single `Result` making a non-existing object an error. | 278 | /// Like [`try_find(…)`](super::Find::try_find()), but flattens the `Result<Option<_>>` into a single `Result` making a non-existing object an error. |
| 220 | fn find<'a>( | 279 | fn find<'a>( |
| 221 | &self, | 280 | &self, |
| 222 | id: &gix_hash::oid, | 281 | id: &gix_hash::oid, |
| @@ -238,6 +297,6 @@ mod find { · 15 unmodified lines |
| 238 | | 297 | |
| 239 | impl<T: super::Find + ?Sized> FindExt for T {} | 298 | impl<T: super::Find + ?Sized> FindExt for T {} |
| 240 | } | 299 | } |
| 241 | pub use ext::FindExt; | 300 | pub use ext::{FindExt, HeaderExt}; |
| 242 | } | 301 | } |
| 243 | pub use find::*; | 302 | pub use find::*; |