1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
use crate::{compound, loose, pack}; use git_object::borrowed; /// Returned by [`compound::Db::locate()`] #[derive(thiserror::Error, Debug)] #[allow(missing_docs)] pub enum Error { #[error("An error occurred while obtaining an object from the loose object store")] Loose(#[from] loose::db::locate::Error), #[error("An error occurred while obtaining an object from the packed object store")] Pack(#[from] pack::data::decode::Error), } impl compound::Db { /// Find an object as identified by [`id`][borrowed::Id] and store its data in full in the provided `buffer`. /// This will search the object in all contained object databases. pub fn locate<'a>( &self, id: borrowed::Id<'_>, buffer: &'a mut Vec<u8>, ) -> Option<Result<compound::Object<'a>, Error>> { for alternate in &self.alternates { // See 8c5bd095539042d7db0e611460803cdbf172beb0 for a commit that adds polonius and makes the proper version compile. // See https://stackoverflow.com/questions/63906425/nll-limitation-how-to-work-around-cannot-borrow-buf-as-mutable-more-than?noredirect=1#comment113007288_63906425 // More see below! Of course we don't want to do the lookup twice… but have to until this is fixed or we compile nightly. if alternate.locate(id, buffer).is_some() { return alternate.locate(id, buffer); } } for pack in &self.packs { // See 8c5bd095539042d7db0e611460803cdbf172beb0 for a commit that adds polonius and makes the proper version compile. // See https://stackoverflow.com/questions/63906425/nll-limitation-how-to-work-around-cannot-borrow-buf-as-mutable-more-than?noredirect=1#comment113007288_63906425 // The underlying issue is described here https://github.com/rust-lang/rust/issues/45402, // Once Polonius becomes a thing AND is not too slow, we must remove this double-lookup to become something like this: // if let Some(object) = if pack.locate(id, buffer, &mut pack::cache::DecodeEntryNoop) {…} if pack.locate(id, buffer, &mut pack::cache::Noop).is_some() { let object = pack.locate(id, buffer, &mut pack::cache::Noop).unwrap(); return Some(object.map(compound::Object::Borrowed).map_err(Into::into)); } } self.loose .locate(id) .map(|object| object.map(compound::Object::Loose).map_err(Into::into)) } }