@@ -3,6 +3,9 @@ use winnow::{error::ParserError, prelude::*};
3
3
4
4
use crate :: { tree, tree:: EntryRef , TreeRef , TreeRefIter } ;
5
5
6
+ /// The error type returned by the [`Tree`](crate::Tree) trait.
7
+ pub type Error = Box < dyn std:: error:: Error + Send + Sync + ' static > ;
8
+
6
9
impl < ' a > TreeRefIter < ' a > {
7
10
/// Instantiate an iterator from the given tree data.
8
11
pub fn from_bytes ( data : & ' a [ u8 ] ) -> TreeRefIter < ' a > {
@@ -47,11 +50,16 @@ impl<'a> TreeRef<'a> {
47
50
///
48
51
/// # Performance Notes
49
52
///
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
51
54
/// to reuse a vector and use a binary search instead, which might be able to improve performance over all.
52
55
/// However, a benchmark should be created first to have some data and see which trade-off to choose here.
53
56
///
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 >
55
63
where
56
64
I : IntoIterator < Item = P > ,
57
65
P : PartialEq < BStr > ,
@@ -62,15 +70,18 @@ impl<'a> TreeRef<'a> {
62
70
match self . entries . iter ( ) . find ( |entry| component. eq ( entry. filename ) ) {
63
71
Some ( entry) => {
64
72
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) ;
68
79
}
69
80
}
70
- None => return None ,
81
+ None => return Ok ( None ) ,
71
82
}
72
83
}
73
- None
84
+ Ok ( None )
74
85
}
75
86
76
87
/// 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> {
79
90
///
80
91
/// If any path component contains illformed UTF-8 and thus can't be converted to bytes on platforms which can't do so natively,
81
92
/// 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 > {
83
99
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
+ )
89
109
}
90
110
91
111
/// Create an instance of the empty tree.
0 commit comments