1
- use std:: collections:: VecDeque ;
2
-
3
1
use gix_hash:: ObjectId ;
4
2
use gix_object:: {
5
3
bstr:: { BStr , BString , ByteSlice , ByteVec } ,
6
4
tree,
7
5
} ;
8
6
9
- use crate :: tree:: visit;
7
+ use crate :: tree:: { visit, Recorder } ;
8
+
9
+ /// Describe how to track the location of a change.
10
+ #[ derive( Debug , Clone , Copy , Eq , PartialEq ) ]
11
+ pub enum Location {
12
+ /// Track the entire path, relative to the repository.
13
+ Path ,
14
+ /// Keep only the file-name as location, which may be enough for some calculations.
15
+ ///
16
+ /// This is less expensive than tracking the entire `Path`.
17
+ FileName ,
18
+ }
10
19
11
20
/// A Change as observed by a call to [`visit(…)`][visit::Visit::visit()], enhanced with the path affected by the change.
12
21
/// Its similar to [visit::Change] but includes the path that changed.
@@ -34,13 +43,37 @@ pub enum Change {
34
43
} ,
35
44
}
36
45
37
- /// A [Visit][visit::Visit] implementation to record every observed change and keep track of the changed paths.
38
- #[ derive( Clone , Debug , Default ) ]
39
- pub struct Recorder {
40
- path_deque : VecDeque < BString > ,
41
- path : BString ,
42
- /// The observed changes.
43
- pub records : Vec < Change > ,
46
+ impl Default for Recorder {
47
+ fn default ( ) -> Self {
48
+ Recorder {
49
+ path_deque : Default :: default ( ) ,
50
+ path : Default :: default ( ) ,
51
+ location : Some ( Location :: Path ) ,
52
+ records : vec ! [ ] ,
53
+ }
54
+ }
55
+ }
56
+
57
+ /// Builder
58
+ impl Recorder {
59
+ /// Obtain a copy of the currently tracked, full path of the entry.
60
+ pub fn track_location ( mut self , location : Option < Location > ) -> Self {
61
+ self . location = location;
62
+ self
63
+ }
64
+ }
65
+
66
+ /// Access
67
+ impl Recorder {
68
+ /// Obtain a copy of the currently tracked, full path of the entry.
69
+ pub fn path_clone ( & self ) -> BString {
70
+ self . path . clone ( )
71
+ }
72
+
73
+ /// Return the currently set path.
74
+ pub fn path ( & self ) -> & BStr {
75
+ self . path . as_ref ( )
76
+ }
44
77
}
45
78
46
79
impl Recorder {
@@ -58,28 +91,39 @@ impl Recorder {
58
91
}
59
92
self . path . push_str ( name) ;
60
93
}
61
-
62
- fn path_clone ( & self ) -> BString {
63
- self . path . clone ( )
64
- }
65
94
}
66
95
67
96
impl visit:: Visit for Recorder {
68
97
fn pop_front_tracked_path_and_set_current ( & mut self ) {
69
- self . path = self . path_deque . pop_front ( ) . expect ( "every parent is set only once" ) ;
98
+ if let Some ( Location :: Path ) = self . location {
99
+ self . path = self . path_deque . pop_front ( ) . expect ( "every parent is set only once" ) ;
100
+ }
70
101
}
71
102
72
103
fn push_back_tracked_path_component ( & mut self , component : & BStr ) {
73
- self . push_element ( component) ;
74
- self . path_deque . push_back ( self . path . clone ( ) ) ;
104
+ if let Some ( Location :: Path ) = self . location {
105
+ self . push_element ( component) ;
106
+ self . path_deque . push_back ( self . path . clone ( ) ) ;
107
+ }
75
108
}
76
109
77
110
fn push_path_component ( & mut self , component : & BStr ) {
78
- self . push_element ( component) ;
111
+ match self . location {
112
+ None => { }
113
+ Some ( Location :: Path ) => {
114
+ self . push_element ( component) ;
115
+ }
116
+ Some ( Location :: FileName ) => {
117
+ self . path . clear ( ) ;
118
+ self . path . extend_from_slice ( component) ;
119
+ }
120
+ }
79
121
}
80
122
81
123
fn pop_path_component ( & mut self ) {
82
- self . pop_element ( ) ;
124
+ if let Some ( Location :: Path ) = self . location {
125
+ self . pop_element ( ) ;
126
+ }
83
127
}
84
128
85
129
fn visit ( & mut self , change : visit:: Change ) -> visit:: Action {
0 commit comments