@@ -2,50 +2,41 @@ use crate::index::diff::Error;
2
2
use crate :: { Change , CrateVersion } ;
3
3
use bstr:: BStr ;
4
4
use git_repository as git;
5
- use git_repository:: diff:: tree:: visit:: Action ;
6
5
use similar:: ChangeTag ;
7
6
use std:: collections:: BTreeSet ;
8
7
9
- pub ( crate ) struct Delegate < ' repo > {
8
+ #[ derive( Default ) ]
9
+ pub ( crate ) struct Delegate {
10
10
changes : Vec < Change > ,
11
11
delete_version_ids : BTreeSet < u64 > ,
12
- file_name : git:: bstr:: BString ,
13
12
err : Option < Error > ,
14
- repo : & ' repo git:: Repository ,
15
13
}
16
14
17
- impl < ' repo > Delegate < ' repo > {
18
- pub fn from_repo ( repo : & ' repo git:: Repository ) -> Self {
19
- Delegate {
20
- changes : Vec :: new ( ) ,
21
- delete_version_ids : BTreeSet :: new ( ) ,
22
- err : None ,
23
- file_name : Default :: default ( ) ,
24
- repo,
25
- }
26
- }
27
- fn handle ( & mut self , change : git:: diff:: tree:: visit:: Change ) -> Result < ( ) , Error > {
15
+ impl Delegate {
16
+ pub fn handle (
17
+ & mut self ,
18
+ change : git:: object:: tree:: diff:: Change < ' _ , ' _ , ' _ > ,
19
+ ) -> Result < git:: object:: tree:: diff:: Action , Error > {
28
20
use git:: bstr:: ByteSlice ;
29
- use git:: diff :: tree:: visit :: Change :: * ;
21
+ use git:: object :: tree:: diff :: change :: Event :: * ;
30
22
use git:: objs:: tree:: EntryMode :: * ;
31
23
fn entry_data (
32
- repo : & git:: Repository ,
33
24
entry : git:: objs:: tree:: EntryMode ,
34
- oid : git:: hash :: ObjectId ,
25
+ id : git:: Id < ' _ > ,
35
26
) -> Result < Option < git:: Object < ' _ > > , Error > {
36
27
matches ! ( entry, Blob | BlobExecutable )
37
- . then ( || repo . find_object ( oid ) )
28
+ . then ( || id . object ( ) )
38
29
. transpose ( )
39
30
. map_err ( Into :: into)
40
31
}
41
- if self . file_name . contains ( & b'.' ) {
42
- return Ok ( ( ) ) ;
32
+ if change . location . contains ( & b'.' ) {
33
+ return Ok ( Default :: default ( ) ) ;
43
34
}
44
- match change {
45
- Addition { entry_mode, oid } => {
46
- if let Some ( obj) = entry_data ( self . repo , entry_mode, oid ) ? {
35
+ match change. event {
36
+ Addition { entry_mode, id } => {
37
+ if let Some ( obj) = entry_data ( entry_mode, id ) ? {
47
38
for line in ( & obj. data ) . lines ( ) {
48
- let version = version_from_json_line ( line, self . file_name . as_ref ( ) ) ?;
39
+ let version = version_from_json_line ( line, change . location ) ?;
49
40
self . changes . push ( if version. yanked {
50
41
Change :: Yanked ( version)
51
42
} else {
@@ -57,29 +48,27 @@ impl<'repo> Delegate<'repo> {
57
48
Deletion { entry_mode, .. } => {
58
49
if entry_mode. is_no_tree ( ) {
59
50
self . changes . push ( Change :: Deleted {
60
- name : self . file_name . to_string ( ) ,
51
+ name : change . location . to_string ( ) ,
61
52
} ) ;
62
53
}
63
54
}
64
55
Modification {
65
56
previous_entry_mode,
66
- previous_oid ,
57
+ previous_id ,
67
58
entry_mode,
68
- oid ,
59
+ id ,
69
60
} => {
70
- let pair = entry_data ( self . repo , previous_entry_mode , previous_oid ) ?
71
- . zip ( entry_data ( self . repo , entry_mode, oid ) ?) ;
61
+ let pair =
62
+ entry_data ( previous_entry_mode , previous_id ) ? . zip ( entry_data ( entry_mode, id ) ?) ;
72
63
if let Some ( ( old, new) ) = pair {
73
64
let diff = similar:: TextDiffConfig :: default ( )
74
65
. algorithm ( similar:: Algorithm :: Myers )
75
66
. diff_lines ( old. data . as_slice ( ) , new. data . as_slice ( ) ) ;
67
+ let location = change. location ;
76
68
for change in diff. iter_all_changes ( ) {
77
69
match change. tag ( ) {
78
70
ChangeTag :: Delete | ChangeTag :: Insert => {
79
- let version = version_from_json_line (
80
- change. value ( ) ,
81
- self . file_name . as_ref ( ) ,
82
- ) ?;
71
+ let version = version_from_json_line ( change. value ( ) , location) ?;
83
72
if change. tag ( ) == ChangeTag :: Insert {
84
73
self . changes . push ( if version. yanked {
85
74
Change :: Yanked ( version)
@@ -96,8 +85,9 @@ impl<'repo> Delegate<'repo> {
96
85
}
97
86
}
98
87
}
99
- Ok ( ( ) )
88
+ Ok ( Default :: default ( ) )
100
89
}
90
+
101
91
pub fn into_result ( mut self ) -> Result < Vec < Change > , Error > {
102
92
match self . err {
103
93
Some ( err) => Err ( err) ,
@@ -117,27 +107,6 @@ impl<'repo> Delegate<'repo> {
117
107
}
118
108
}
119
109
120
- impl git:: diff:: tree:: Visit for Delegate < ' _ > {
121
- fn pop_front_tracked_path_and_set_current ( & mut self ) { }
122
- fn push_back_tracked_path_component ( & mut self , _component : & git:: bstr:: BStr ) { }
123
- fn push_path_component ( & mut self , component : & git:: bstr:: BStr ) {
124
- use git:: bstr:: ByteVec ;
125
- self . file_name . clear ( ) ;
126
- self . file_name . push_str ( component) ;
127
- }
128
- fn pop_path_component ( & mut self ) { }
129
-
130
- fn visit ( & mut self , change : git:: diff:: tree:: visit:: Change ) -> Action {
131
- match self . handle ( change) {
132
- Ok ( ( ) ) => Action :: Continue ,
133
- Err ( err) => {
134
- self . err = err. into ( ) ;
135
- Action :: Cancel
136
- }
137
- }
138
- }
139
- }
140
-
141
110
fn version_from_json_line ( line : & [ u8 ] , file_name : & BStr ) -> Result < CrateVersion , Error > {
142
111
serde_json:: from_slice ( line) . map_err ( |err| Error :: VersionDecode {
143
112
source : err,
0 commit comments