History

feat: support for querying only the header of an object with the `FindHeader` trait.

That way one can know its decompressed size and its kind. We also add a `FindObjectOrHeader` trait for use as `dyn` trait object that can find objects and access their headers.

Sebastian Thiel committed 2 years ago

Commit 1838cbd1 parent f09ea133 files · +77 −3Browse files

Unified · Split

3 files
  1. gix-object/src/find.rs +6 −0
  2. gix-object/src/lib.rs +10 −1
  3. gix-object/src/traits.rs +61 −2
gix-object/src/find.rs+6−0
@@ -66,6 +66,12 @@ pub mod existing_iter { · 65 unmodified lines
66#[derive(Debug, Copy, Clone)]66#[derive(Debug, Copy, Clone)]
67pub struct Never;67pub struct Never;
68 68
69impl super::FindHeader for Never {
70 fn try_header(&self, _id: &gix_hash::oid) -> Result<Option<crate::Header>, Error> {
71 Ok(None)
72 }
73}
74
69impl super::Find for Never {75impl super::Find for Never {
70 fn try_find<'a>(&self, _id: &gix_hash::oid, _buffer: &'a mut Vec<u8>) -> Result<Option<crate::Data<'a>>, Error> {76 fn try_find<'a>(&self, _id: &gix_hash::oid, _buffer: &'a mut Vec<u8>) -> Result<Option<crate::Data<'a>>, Error> {
71 Ok(None)77 Ok(None)
gix-object/src/lib.rs+10−1
@@ -34,7 +34,7 @@ pub mod data; · 33 unmodified lines
34pub mod find;34pub mod find;
35 35
36mod traits;36mod traits;
37pub use traits::{Exists, Find, FindExt, WriteTo};37pub use traits::{Exists, Find, FindExt, FindObjectOrHeader, Header as FindHeader, HeaderExt, WriteTo};
38 38
39pub mod encode;39pub mod encode;
40pub(crate) mod parse;40pub(crate) mod parse;
@@ -257,6 +257,15 @@ pub struct Data<'a> { · 216 unmodified lines
257 pub data: &'a [u8],257 pub data: &'a [u8],
258}258}
259 259
260/// Information about an object, which includes its kind and the amount of bytes it would have when obtained.
261#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
262pub struct Header {
263 /// The kind of object.
264 pub kind: Kind,
265 /// The object's size in bytes, or the size of the buffer when it's retrieved in full.
266 pub size: u64,
267}
268
260///269///
261pub mod decode {270pub mod decode {
262 #[cfg(feature = "verbose-object-parsing-errors")]271 #[cfg(feature = "verbose-object-parsing-errors")]
gix-object/src/traits.rs+61−2
@@ -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 &T102 impl<T> crate::Find for &T
90 where103 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 where121 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 where157 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 where175 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}
243pub use find::*;302pub use find::*;