@@ -3,6 +3,9 @@ use winnow::{error::ParserError, prelude::*};
33
44use crate :: { tree, tree:: EntryRef , TreeRef , TreeRefIter } ;
55
6+ /// The error type returned by the [`Tree`](crate::Tree) trait.
7+ pub type Error = Box < dyn std:: error:: Error + Send + Sync + ' static > ;
8+
69impl < ' a > TreeRefIter < ' a > {
710 /// Instantiate an iterator from the given tree data.
811 pub fn from_bytes ( data : & ' a [ u8 ] ) -> TreeRefIter < ' a > {
@@ -47,11 +50,16 @@ impl<'a> TreeRef<'a> {
4750 ///
4851 /// # Performance Notes
4952 ///
50- /// Searching tree entries is currently done in sequence, which allows to the search to be allocation free. It would be possible
53+ /// Searching tree entries is currently done in sequence, which allows the search to be allocation free. It would be possible
5154 /// to reuse a vector and use a binary search instead, which might be able to improve performance over all.
5255 /// However, a benchmark should be created first to have some data and see which trade-off to choose here.
5356 ///
54- pub fn lookup_entry < I , P > ( & self , path : I ) -> Option < EntryRef < ' a > >
57+ pub fn lookup_entry < I , P > (
58+ & self ,
59+ odb : impl crate :: Find + crate :: FindExt ,
60+ buffer : & ' a mut Vec < u8 > ,
61+ path : I ,
62+ ) -> Result < Option < EntryRef < ' a > > , Error >
5563 where
5664 I : IntoIterator < Item = P > ,
5765 P : PartialEq < BStr > ,
@@ -62,15 +70,18 @@ impl<'a> TreeRef<'a> {
6270 match self . entries . iter ( ) . find ( |entry| component. eq ( entry. filename ) ) {
6371 Some ( entry) => {
6472 if path. peek ( ) . is_none ( ) {
65- return Some ( * entry) ;
66- } else if !entry. mode . is_tree ( ) {
67- return None ;
73+ return Ok ( Some ( * entry) ) ;
74+ } else {
75+ let next_id = entry. oid . to_owned ( ) ;
76+ let obj = odb. find_tree ( & next_id, buffer) ?;
77+
78+ return obj. lookup_entry ( odb, buffer, path) ;
6879 }
6980 }
70- None => return None ,
81+ None => return Ok ( None ) ,
7182 }
7283 }
73- None
84+ Ok ( None )
7485 }
7586
7687 /// Like [`Self::lookup_entry()`], but takes a `Path` directly via `relative_path`, a path relative to this tree.
@@ -79,13 +90,22 @@ impl<'a> TreeRef<'a> {
7990 ///
8091 /// If any path component contains illformed UTF-8 and thus can't be converted to bytes on platforms which can't do so natively,
8192 /// the returned component will be empty which makes the lookup fail.
82- pub fn lookup_entry_by_path ( & self , relative_path : impl AsRef < std:: path:: Path > ) -> Option < EntryRef < ' a > > {
93+ pub fn lookup_entry_by_path (
94+ & self ,
95+ odb : impl crate :: Find ,
96+ buffer : & ' a mut Vec < u8 > ,
97+ relative_path : impl AsRef < std:: path:: Path > ,
98+ ) -> Result < Option < EntryRef < ' a > > , Error > {
8399 use crate :: bstr:: ByteSlice ;
84- self . lookup_entry ( relative_path. as_ref ( ) . components ( ) . map ( |c : std:: path:: Component < ' _ > | {
85- gix_path:: os_str_into_bstr ( c. as_os_str ( ) )
86- . unwrap_or_else ( |_| "" . into ( ) )
87- . as_bytes ( )
88- } ) )
100+ self . lookup_entry (
101+ odb,
102+ buffer,
103+ relative_path. as_ref ( ) . components ( ) . map ( |c : std:: path:: Component < ' _ > | {
104+ gix_path:: os_str_into_bstr ( c. as_os_str ( ) )
105+ . unwrap_or_else ( |_| "" . into ( ) )
106+ . as_bytes ( )
107+ } ) ,
108+ )
89109 }
90110
91111 /// Create an instance of the empty tree.
0 commit comments