git_pack/bundle/
find.rs

1impl crate::Bundle {
2    /// Find an object with the given [`ObjectId`][git_hash::ObjectId] and place its data into `out`.
3    ///
4    /// [`cache`][crate::cache::DecodeEntry] is used to accelerate the lookup.
5    ///
6    /// **Note** that ref deltas are automatically resolved within this pack only, which makes this implementation unusable
7    /// for thin packs, which by now are expected to be resolved already.
8    pub fn find<'a>(
9        &self,
10        id: impl AsRef<git_hash::oid>,
11        out: &'a mut Vec<u8>,
12        cache: &mut impl crate::cache::DecodeEntry,
13    ) -> Result<Option<(git_object::Data<'a>, crate::data::entry::Location)>, crate::data::decode::Error> {
14        let idx = match self.index.lookup(id) {
15            Some(idx) => idx,
16            None => return Ok(None),
17        };
18        self.get_object_by_index(idx, out, cache).map(Some)
19    }
20
21    /// Special-use function to get an object given an index previously returned from
22    /// internal_find_pack_index.
23    ///
24    /// # Panics
25    ///
26    /// If `index` is out of bounds.
27    pub fn get_object_by_index<'a>(
28        &self,
29        idx: u32,
30        out: &'a mut Vec<u8>,
31        cache: &mut impl crate::cache::DecodeEntry,
32    ) -> Result<(git_object::Data<'a>, crate::data::entry::Location), crate::data::decode::Error> {
33        let ofs = self.index.pack_offset_at_index(idx);
34        let pack_entry = self.pack.entry(ofs);
35        let header_size = pack_entry.header_size();
36        self.pack
37            .decode_entry(
38                pack_entry,
39                out,
40                |id, _out| {
41                    self.index.lookup(id).map(|idx| {
42                        crate::data::decode::entry::ResolvedBase::InPack(
43                            self.pack.entry(self.index.pack_offset_at_index(idx)),
44                        )
45                    })
46                },
47                cache,
48            )
49            .map(move |r| {
50                (
51                    git_object::Data {
52                        kind: r.kind,
53                        data: out.as_slice(),
54                    },
55                    crate::data::entry::Location {
56                        pack_id: self.pack.id,
57                        pack_offset: ofs,
58                        entry_size: r.compressed_size + header_size,
59                    },
60                )
61            })
62    }
63}