Adapt functions to new context. This mostly means copying the implementation from `gix::types::Tree` and applying minor changes related to `buffer` being passed as an argument.
Unified · Split
| @@ -11,39 +11,6 @@ impl<'a> TreeRefIter<'a> { · 10 unmodified lines | |||
| 11 | pub fn from_bytes(data: &'a [u8]) -> TreeRefIter<'a> { | 11 | pub fn from_bytes(data: &'a [u8]) -> TreeRefIter<'a> { |
| 12 | TreeRefIter { data } | 12 | TreeRefIter { data } |
| 13 | } | 13 | } |
| 14 | } | ||
| 15 | |||
| 16 | impl<'a> TreeRef<'a> { | ||
| 17 | /// Deserialize a Tree from `data`. | ||
| 18 | pub fn from_bytes(mut data: &'a [u8]) -> Result<TreeRef<'a>, crate::decode::Error> { | ||
| 19 | let input = &mut data; | ||
| 20 | match decode::tree.parse_next(input) { | ||
| 21 | Ok(tag) => Ok(tag), | ||
| 22 | Err(err) => Err(crate::decode::Error::with_err(err, input)), | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 26 | /// Find an entry named `name` knowing if the entry is a directory or not, using a binary search. | ||
| 27 | /// | ||
| 28 | /// Note that it's impossible to binary search by name alone as the sort order is special. | ||
| 29 | pub fn bisect_entry(&self, name: &BStr, is_dir: bool) -> Option<EntryRef<'a>> { | ||
| 30 | static NULL_HASH: gix_hash::ObjectId = gix_hash::Kind::shortest().null(); | ||
| 31 | |||
| 32 | let search = EntryRef { | ||
| 33 | mode: if is_dir { | ||
| 34 | tree::EntryKind::Tree | ||
| 35 | } else { | ||
| 36 | tree::EntryKind::Blob | ||
| 37 | } | ||
| 38 | .into(), | ||
| 39 | filename: name, | ||
| 40 | oid: &NULL_HASH, | ||
| 41 | }; | ||
| 42 | self.entries | ||
| 43 | .binary_search_by(|e| e.cmp(&search)) | ||
| 44 | .ok() | ||
| 45 | .map(|idx| self.entries[idx]) | ||
| 46 | } | ||
| 47 | 14 | ||
| 48 | /// Follow a sequence of `path` components starting from this instance, and look them up one by one until the last component | 15 | /// Follow a sequence of `path` components starting from this instance, and look them up one by one until the last component |
| 49 | /// is looked up and its tree entry is returned. | 16 | /// is looked up and its tree entry is returned. |
| @@ -64,19 +31,24 @@ impl<'a> TreeRef<'a> { · 14 unmodified lines | |||
| 64 | I: IntoIterator<Item = P>, | 31 | I: IntoIterator<Item = P>, |
| 65 | P: PartialEq<BStr>, | 32 | P: PartialEq<BStr>, |
| 66 | { | 33 | { |
| 67 | let mut path = path.into_iter().peekable(); | 34 | buffer.clear(); |
| 68 | let mut entries = self.entries.clone(); | ||
| 69 | 35 | ||
| 36 | let mut path = path.into_iter().peekable(); | ||
| 37 | buffer.extend_from_slice(&self.data); | ||
| 70 | while let Some(component) = path.next() { | 38 | while let Some(component) = path.next() { |
| 71 | match entries.iter().find(|entry| component.eq(entry.filename)) { | 39 | match TreeRefIter::from_bytes(&buffer) |
| 40 | .filter_map(Result::ok) | ||
| 41 | .find(|entry| component.eq(entry.filename)) | ||
| 42 | { | ||
| 72 | Some(entry) => { | 43 | Some(entry) => { |
| 73 | if path.peek().is_none() { | 44 | if path.peek().is_none() { |
| 74 | return Ok(Some((*entry).into())); | 45 | return Ok(Some(entry.into())); |
| 75 | } else { | 46 | } else { |
| 76 | let next_id = entry.oid.to_owned(); | 47 | let next_id = entry.oid.to_owned(); |
| 77 | let obj = odb.find_tree(&next_id, buffer)?; | 48 | let obj = odb.find(&next_id, buffer)?; |
| 78 | 49 | if !obj.kind.is_tree() { | |
| 79 | entries = obj.entries; | 50 | return Ok(None); |
| 51 | } | ||
| 80 | } | 52 | } |
| 81 | } | 53 | } |
| 82 | None => return Ok(None), | 54 | None => return Ok(None), |
| @@ -108,6 +80,39 @@ impl<'a> TreeRef<'a> { · 25 unmodified lines | |||
| 108 | }), | 80 | }), |
| 109 | ) | 81 | ) |
| 110 | } | 82 | } |
| 83 | } | ||
| 84 | |||
| 85 | impl<'a> TreeRef<'a> { | ||
| 86 | /// Deserialize a Tree from `data`. | ||
| 87 | pub fn from_bytes(mut data: &'a [u8]) -> Result<TreeRef<'a>, crate::decode::Error> { | ||
| 88 | let input = &mut data; | ||
| 89 | match decode::tree.parse_next(input) { | ||
| 90 | Ok(tag) => Ok(tag), | ||
| 91 | Err(err) => Err(crate::decode::Error::with_err(err, input)), | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | /// Find an entry named `name` knowing if the entry is a directory or not, using a binary search. | ||
| 96 | /// | ||
| 97 | /// Note that it's impossible to binary search by name alone as the sort order is special. | ||
| 98 | pub fn bisect_entry(&self, name: &BStr, is_dir: bool) -> Option<EntryRef<'a>> { | ||
| 99 | static NULL_HASH: gix_hash::ObjectId = gix_hash::Kind::shortest().null(); | ||
| 100 | |||
| 101 | let search = EntryRef { | ||
| 102 | mode: if is_dir { | ||
| 103 | tree::EntryKind::Tree | ||
| 104 | } else { | ||
| 105 | tree::EntryKind::Blob | ||
| 106 | } | ||
| 107 | .into(), | ||
| 108 | filename: name, | ||
| 109 | oid: &NULL_HASH, | ||
| 110 | }; | ||
| 111 | self.entries | ||
| 112 | .binary_search_by(|e| e.cmp(&search)) | ||
| 113 | .ok() | ||
| 114 | .map(|idx| self.entries[idx]) | ||
| 115 | } | ||
| 111 | 116 | ||
| 112 | /// Create an instance of the empty tree. | 117 | /// Create an instance of the empty tree. |
| 113 | /// | 118 | /// |
| @@ -64,7 +64,7 @@ fn lookup_entry_toplevel() -> crate::Result { · 63 unmodified lines | |||
| 64 | let root_tree_id = hex_to_id("ff7e7d2aecae1c3fb15054b289a4c58aa65b8646"); | 64 | let root_tree_id = hex_to_id("ff7e7d2aecae1c3fb15054b289a4c58aa65b8646"); |
| 65 | 65 | ||
| 66 | let mut buf = Vec::new(); | 66 | let mut buf = Vec::new(); |
| 67 | let root_tree = odb.find_tree(&root_tree_id, &mut buf)?; | 67 | let root_tree = odb.find_tree_iter(&root_tree_id, &mut buf)?; |
| 68 | 68 | ||
| 69 | let mut buf = Vec::new(); | 69 | let mut buf = Vec::new(); |
| 70 | let entry = root_tree.lookup_entry_by_path(&odb, &mut buf, "bin").unwrap().unwrap(); | 70 | let entry = root_tree.lookup_entry_by_path(&odb, &mut buf, "bin").unwrap().unwrap(); |
| @@ -81,7 +81,7 @@ fn lookup_entry_nested_path() -> crate::Result { · 10 unmodified lines | |||
| 81 | let root_tree_id = hex_to_id("ff7e7d2aecae1c3fb15054b289a4c58aa65b8646"); | 81 | let root_tree_id = hex_to_id("ff7e7d2aecae1c3fb15054b289a4c58aa65b8646"); |
| 82 | 82 | ||
| 83 | let mut buf = Vec::new(); | 83 | let mut buf = Vec::new(); |
| 84 | let root_tree = odb.find_tree(&root_tree_id, &mut buf)?; | 84 | let root_tree = odb.find_tree_iter(&root_tree_id, &mut buf)?; |
| 85 | 85 | ||
| 86 | let mut buf = Vec::new(); | 86 | let mut buf = Vec::new(); |
| 87 | let entry = root_tree | 87 | let entry = root_tree |