##// END OF EJS Templates
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
Raphaël Gomès -
r43227:7a01778b default
parent child Browse files
Show More
@@ -5,7 +5,7 b''
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 use crate::DirstateParseError;
8 use crate::{utils::hg_path::HgPathBuf, DirstateParseError};
9 use std::collections::hash_map;
9 use std::collections::hash_map;
10 use std::collections::HashMap;
10 use std::collections::HashMap;
11 use std::convert::TryFrom;
11 use std::convert::TryFrom;
@@ -31,10 +31,10 b' pub struct DirstateEntry {'
31 pub size: i32,
31 pub size: i32,
32 }
32 }
33
33
34 pub type StateMap = HashMap<Vec<u8>, DirstateEntry>;
34 pub type StateMap = HashMap<HgPathBuf, DirstateEntry>;
35 pub type StateMapIter<'a> = hash_map::Iter<'a, Vec<u8>, DirstateEntry>;
35 pub type StateMapIter<'a> = hash_map::Iter<'a, HgPathBuf, DirstateEntry>;
36 pub type CopyMap = HashMap<Vec<u8>, Vec<u8>>;
36 pub type CopyMap = HashMap<HgPathBuf, HgPathBuf>;
37 pub type CopyMapIter<'a> = hash_map::Iter<'a, Vec<u8>, Vec<u8>>;
37 pub type CopyMapIter<'a> = hash_map::Iter<'a, HgPathBuf, HgPathBuf>;
38
38
39 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
39 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
40 pub enum EntryState {
40 pub enum EntryState {
@@ -8,6 +8,7 b''
8 //! A multiset of directory names.
8 //! A multiset of directory names.
9 //!
9 //!
10 //! Used to counts the references to directories in a manifest or dirstate.
10 //! Used to counts the references to directories in a manifest or dirstate.
11 use crate::utils::hg_path::{HgPath, HgPathBuf};
11 use crate::{
12 use crate::{
12 dirstate::EntryState, utils::files, DirstateEntry, DirstateMapError,
13 dirstate::EntryState, utils::files, DirstateEntry, DirstateMapError,
13 };
14 };
@@ -15,11 +16,11 b' use std::collections::hash_map::{self, E'
15 use std::collections::HashMap;
16 use std::collections::HashMap;
16
17
17 // could be encapsulated if we care API stability more seriously
18 // could be encapsulated if we care API stability more seriously
18 pub type DirsMultisetIter<'a> = hash_map::Keys<'a, Vec<u8>, u32>;
19 pub type DirsMultisetIter<'a> = hash_map::Keys<'a, HgPathBuf, u32>;
19
20
20 #[derive(PartialEq, Debug)]
21 #[derive(PartialEq, Debug)]
21 pub struct DirsMultiset {
22 pub struct DirsMultiset {
22 inner: HashMap<Vec<u8>, u32>,
23 inner: HashMap<HgPathBuf, u32>,
23 }
24 }
24
25
25 impl DirsMultiset {
26 impl DirsMultiset {
@@ -27,7 +28,7 b' impl DirsMultiset {'
27 ///
28 ///
28 /// If `skip_state` is provided, skips dirstate entries with equal state.
29 /// If `skip_state` is provided, skips dirstate entries with equal state.
29 pub fn from_dirstate(
30 pub fn from_dirstate(
30 vec: &HashMap<Vec<u8>, DirstateEntry>,
31 vec: &HashMap<HgPathBuf, DirstateEntry>,
31 skip_state: Option<EntryState>,
32 skip_state: Option<EntryState>,
32 ) -> Self {
33 ) -> Self {
33 let mut multiset = DirsMultiset {
34 let mut multiset = DirsMultiset {
@@ -49,7 +50,7 b' impl DirsMultiset {'
49 }
50 }
50
51
51 /// Initializes the multiset from a manifest.
52 /// Initializes the multiset from a manifest.
52 pub fn from_manifest(vec: &Vec<Vec<u8>>) -> Self {
53 pub fn from_manifest(vec: &Vec<HgPathBuf>) -> Self {
53 let mut multiset = DirsMultiset {
54 let mut multiset = DirsMultiset {
54 inner: HashMap::new(),
55 inner: HashMap::new(),
55 };
56 };
@@ -64,7 +65,7 b' impl DirsMultiset {'
64 /// Increases the count of deepest directory contained in the path.
65 /// Increases the count of deepest directory contained in the path.
65 ///
66 ///
66 /// If the directory is not yet in the map, adds its parents.
67 /// If the directory is not yet in the map, adds its parents.
67 pub fn add_path(&mut self, path: &[u8]) {
68 pub fn add_path(&mut self, path: &HgPath) {
68 for subpath in files::find_dirs(path) {
69 for subpath in files::find_dirs(path) {
69 if let Some(val) = self.inner.get_mut(subpath) {
70 if let Some(val) = self.inner.get_mut(subpath) {
70 *val += 1;
71 *val += 1;
@@ -81,7 +82,7 b' impl DirsMultiset {'
81 /// If the directory is not in the map, something horrible has happened.
82 /// If the directory is not in the map, something horrible has happened.
82 pub fn delete_path(
83 pub fn delete_path(
83 &mut self,
84 &mut self,
84 path: &[u8],
85 path: &HgPath,
85 ) -> Result<(), DirstateMapError> {
86 ) -> Result<(), DirstateMapError> {
86 for subpath in files::find_dirs(path) {
87 for subpath in files::find_dirs(path) {
87 match self.inner.entry(subpath.to_owned()) {
88 match self.inner.entry(subpath.to_owned()) {
@@ -104,7 +105,7 b' impl DirsMultiset {'
104 Ok(())
105 Ok(())
105 }
106 }
106
107
107 pub fn contains(&self, key: &[u8]) -> bool {
108 pub fn contains(&self, key: &HgPath) -> bool {
108 self.inner.contains_key(key)
109 self.inner.contains_key(key)
109 }
110 }
110
111
@@ -125,20 +126,20 b' mod tests {'
125 #[test]
126 #[test]
126 fn test_delete_path_path_not_found() {
127 fn test_delete_path_path_not_found() {
127 let mut map = DirsMultiset::from_manifest(&vec![]);
128 let mut map = DirsMultiset::from_manifest(&vec![]);
128 let path = b"doesnotexist/";
129 let path = HgPathBuf::from_bytes(b"doesnotexist/");
129 assert_eq!(
130 assert_eq!(
130 Err(DirstateMapError::PathNotFound(path.to_vec())),
131 Err(DirstateMapError::PathNotFound(path.to_owned())),
131 map.delete_path(path)
132 map.delete_path(&path)
132 );
133 );
133 }
134 }
134
135
135 #[test]
136 #[test]
136 fn test_delete_path_empty_path() {
137 fn test_delete_path_empty_path() {
137 let mut map = DirsMultiset::from_manifest(&vec![vec![]]);
138 let mut map = DirsMultiset::from_manifest(&vec![HgPathBuf::new()]);
138 let path = b"";
139 let path = HgPath::new(b"");
139 assert_eq!(Ok(()), map.delete_path(path));
140 assert_eq!(Ok(()), map.delete_path(path));
140 assert_eq!(
141 assert_eq!(
141 Err(DirstateMapError::PathNotFound(path.to_vec())),
142 Err(DirstateMapError::PathNotFound(path.to_owned())),
142 map.delete_path(path)
143 map.delete_path(path)
143 );
144 );
144 }
145 }
@@ -148,34 +149,40 b' mod tests {'
148 let mut map = DirsMultiset {
149 let mut map = DirsMultiset {
149 inner: [("", 5), ("a", 3), ("a/b", 2), ("a/c", 1)]
150 inner: [("", 5), ("a", 3), ("a/b", 2), ("a/c", 1)]
150 .iter()
151 .iter()
151 .map(|(k, v)| (k.as_bytes().to_vec(), *v))
152 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v))
152 .collect(),
153 .collect(),
153 };
154 };
154
155
155 assert_eq!(Ok(()), map.delete_path(b"a/b/"));
156 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/b/")));
156 assert_eq!(Ok(()), map.delete_path(b"a/b/"));
157 eprintln!("{:?}", map);
158 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/b/")));
159 eprintln!("{:?}", map);
157 assert_eq!(
160 assert_eq!(
158 Err(DirstateMapError::PathNotFound(b"a/b/".to_vec())),
161 Err(DirstateMapError::PathNotFound(HgPathBuf::from_bytes(
159 map.delete_path(b"a/b/")
162 b"a/b/"
163 ))),
164 map.delete_path(HgPath::new(b"a/b/"))
160 );
165 );
161
166
162 assert_eq!(2, *map.inner.get(&b"a".to_vec()).unwrap());
167 assert_eq!(2, *map.inner.get(HgPath::new(b"a")).unwrap());
163 assert_eq!(1, *map.inner.get(&b"a/c".to_vec()).unwrap());
168 assert_eq!(1, *map.inner.get(HgPath::new(b"a/c")).unwrap());
164 eprintln!("{:?}", map);
169 eprintln!("{:?}", map);
165 assert_eq!(Ok(()), map.delete_path(b"a/"));
170 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/")));
166 eprintln!("{:?}", map);
171 eprintln!("{:?}", map);
167
172
168 assert_eq!(Ok(()), map.delete_path(b"a/c/"));
173 assert_eq!(Ok(()), map.delete_path(HgPath::new(b"a/c/")));
169 assert_eq!(
174 assert_eq!(
170 Err(DirstateMapError::PathNotFound(b"a/c/".to_vec())),
175 Err(DirstateMapError::PathNotFound(HgPathBuf::from_bytes(
171 map.delete_path(b"a/c/")
176 b"a/c/"
177 ))),
178 map.delete_path(HgPath::new(b"a/c/"))
172 );
179 );
173 }
180 }
174
181
175 #[test]
182 #[test]
176 fn test_add_path_empty_path() {
183 fn test_add_path_empty_path() {
177 let mut map = DirsMultiset::from_manifest(&vec![]);
184 let mut map = DirsMultiset::from_manifest(&vec![]);
178 let path = b"";
185 let path = HgPath::new(b"");
179 map.add_path(path);
186 map.add_path(path);
180
187
181 assert_eq!(1, map.len());
188 assert_eq!(1, map.len());
@@ -185,42 +192,42 b' mod tests {'
185 fn test_add_path_successful() {
192 fn test_add_path_successful() {
186 let mut map = DirsMultiset::from_manifest(&vec![]);
193 let mut map = DirsMultiset::from_manifest(&vec![]);
187
194
188 map.add_path(b"a/");
195 map.add_path(HgPath::new(b"a/"));
189 assert_eq!(1, *map.inner.get(&b"a".to_vec()).unwrap());
196 assert_eq!(1, *map.inner.get(HgPath::new(b"a")).unwrap());
190 assert_eq!(1, *map.inner.get(&Vec::new()).unwrap());
197 assert_eq!(1, *map.inner.get(HgPath::new(b"")).unwrap());
191 assert_eq!(2, map.len());
198 assert_eq!(2, map.len());
192
199
193 // Non directory should be ignored
200 // Non directory should be ignored
194 map.add_path(b"a");
201 map.add_path(HgPath::new(b"a"));
195 assert_eq!(1, *map.inner.get(&b"a".to_vec()).unwrap());
202 assert_eq!(1, *map.inner.get(HgPath::new(b"a")).unwrap());
196 assert_eq!(2, map.len());
203 assert_eq!(2, map.len());
197
204
198 // Non directory will still add its base
205 // Non directory will still add its base
199 map.add_path(b"a/b");
206 map.add_path(HgPath::new(b"a/b"));
200 assert_eq!(2, *map.inner.get(&b"a".to_vec()).unwrap());
207 assert_eq!(2, *map.inner.get(HgPath::new(b"a")).unwrap());
201 assert_eq!(2, map.len());
208 assert_eq!(2, map.len());
202
209
203 // Duplicate path works
210 // Duplicate path works
204 map.add_path(b"a/");
211 map.add_path(HgPath::new(b"a/"));
205 assert_eq!(3, *map.inner.get(&b"a".to_vec()).unwrap());
212 assert_eq!(3, *map.inner.get(HgPath::new(b"a")).unwrap());
206
213
207 // Nested dir adds to its base
214 // Nested dir adds to its base
208 map.add_path(b"a/b/");
215 map.add_path(HgPath::new(b"a/b/"));
209 assert_eq!(4, *map.inner.get(&b"a".to_vec()).unwrap());
216 assert_eq!(4, *map.inner.get(HgPath::new(b"a")).unwrap());
210 assert_eq!(1, *map.inner.get(&b"a/b".to_vec()).unwrap());
217 assert_eq!(1, *map.inner.get(HgPath::new(b"a/b")).unwrap());
211
218
212 // but not its base's base, because it already existed
219 // but not its base's base, because it already existed
213 map.add_path(b"a/b/c/");
220 map.add_path(HgPath::new(b"a/b/c/"));
214 assert_eq!(4, *map.inner.get(&b"a".to_vec()).unwrap());
221 assert_eq!(4, *map.inner.get(HgPath::new(b"a")).unwrap());
215 assert_eq!(2, *map.inner.get(&b"a/b".to_vec()).unwrap());
222 assert_eq!(2, *map.inner.get(HgPath::new(b"a/b")).unwrap());
216
223
217 map.add_path(b"a/c/");
224 map.add_path(HgPath::new(b"a/c/"));
218 assert_eq!(1, *map.inner.get(&b"a/c".to_vec()).unwrap());
225 assert_eq!(1, *map.inner.get(HgPath::new(b"a/c")).unwrap());
219
226
220 let expected = DirsMultiset {
227 let expected = DirsMultiset {
221 inner: [("", 2), ("a", 5), ("a/b", 2), ("a/b/c", 1), ("a/c", 1)]
228 inner: [("", 2), ("a", 5), ("a/b", 2), ("a/b/c", 1), ("a/c", 1)]
222 .iter()
229 .iter()
223 .map(|(k, v)| (k.as_bytes().to_vec(), *v))
230 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v))
224 .collect(),
231 .collect(),
225 };
232 };
226 assert_eq!(map, expected);
233 assert_eq!(map, expected);
@@ -245,11 +252,11 b' mod tests {'
245 fn test_dirsmultiset_new_no_skip() {
252 fn test_dirsmultiset_new_no_skip() {
246 let input_vec = ["a/", "b/", "a/c", "a/d/"]
253 let input_vec = ["a/", "b/", "a/c", "a/d/"]
247 .iter()
254 .iter()
248 .map(|e| e.as_bytes().to_vec())
255 .map(|e| HgPathBuf::from_bytes(e.as_bytes()))
249 .collect();
256 .collect();
250 let expected_inner = [("", 2), ("a", 3), ("b", 1), ("a/d", 1)]
257 let expected_inner = [("", 2), ("a", 3), ("b", 1), ("a/d", 1)]
251 .iter()
258 .iter()
252 .map(|(k, v)| (k.as_bytes().to_vec(), *v))
259 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v))
253 .collect();
260 .collect();
254
261
255 let new = DirsMultiset::from_manifest(&input_vec);
262 let new = DirsMultiset::from_manifest(&input_vec);
@@ -262,7 +269,7 b' mod tests {'
262 .iter()
269 .iter()
263 .map(|f| {
270 .map(|f| {
264 (
271 (
265 f.as_bytes().to_vec(),
272 HgPathBuf::from_bytes(f.as_bytes()),
266 DirstateEntry {
273 DirstateEntry {
267 state: EntryState::Normal,
274 state: EntryState::Normal,
268 mode: 0,
275 mode: 0,
@@ -274,7 +281,7 b' mod tests {'
274 .collect();
281 .collect();
275 let expected_inner = [("", 2), ("a", 3), ("b", 1), ("a/d", 1)]
282 let expected_inner = [("", 2), ("a", 3), ("b", 1), ("a/d", 1)]
276 .iter()
283 .iter()
277 .map(|(k, v)| (k.as_bytes().to_vec(), *v))
284 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v))
278 .collect();
285 .collect();
279
286
280 let new = DirsMultiset::from_dirstate(&input_map, None);
287 let new = DirsMultiset::from_dirstate(&input_map, None);
@@ -295,7 +302,7 b' mod tests {'
295 .iter()
302 .iter()
296 .map(|(f, state)| {
303 .map(|(f, state)| {
297 (
304 (
298 f.as_bytes().to_vec(),
305 HgPathBuf::from_bytes(f.as_bytes()),
299 DirstateEntry {
306 DirstateEntry {
300 state: *state,
307 state: *state,
301 mode: 0,
308 mode: 0,
@@ -309,7 +316,7 b' mod tests {'
309 // "a" incremented with "a/c" and "a/d/"
316 // "a" incremented with "a/c" and "a/d/"
310 let expected_inner = [("", 1), ("a", 2), ("a/d", 1)]
317 let expected_inner = [("", 1), ("a", 2), ("a/d", 1)]
311 .iter()
318 .iter()
312 .map(|(k, v)| (k.as_bytes().to_vec(), *v))
319 .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v))
313 .collect();
320 .collect();
314
321
315 let new =
322 let new =
@@ -5,6 +5,7 b''
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 use crate::utils::hg_path::{HgPath, HgPathBuf};
8 use crate::{
9 use crate::{
9 dirstate::{parsers::PARENT_SIZE, EntryState},
10 dirstate::{parsers::PARENT_SIZE, EntryState},
10 pack_dirstate, parse_dirstate,
11 pack_dirstate, parse_dirstate,
@@ -19,7 +20,7 b' use std::iter::FromIterator;'
19 use std::ops::Deref;
20 use std::ops::Deref;
20 use std::time::Duration;
21 use std::time::Duration;
21
22
22 pub type FileFoldMap = HashMap<Vec<u8>, Vec<u8>>;
23 pub type FileFoldMap = HashMap<HgPathBuf, HgPathBuf>;
23
24
24 const NULL_ID: [u8; 20] = [0; 20];
25 const NULL_ID: [u8; 20] = [0; 20];
25 const MTIME_UNSET: i32 = -1;
26 const MTIME_UNSET: i32 = -1;
@@ -32,8 +33,8 b' pub struct DirstateMap {'
32 file_fold_map: Option<FileFoldMap>,
33 file_fold_map: Option<FileFoldMap>,
33 pub dirs: Option<DirsMultiset>,
34 pub dirs: Option<DirsMultiset>,
34 pub all_dirs: Option<DirsMultiset>,
35 pub all_dirs: Option<DirsMultiset>,
35 non_normal_set: HashSet<Vec<u8>>,
36 non_normal_set: HashSet<HgPathBuf>,
36 other_parent_set: HashSet<Vec<u8>>,
37 other_parent_set: HashSet<HgPathBuf>,
37 parents: Option<DirstateParents>,
38 parents: Option<DirstateParents>,
38 dirty_parents: bool,
39 dirty_parents: bool,
39 }
40 }
@@ -47,8 +48,8 b' impl Deref for DirstateMap {'
47 }
48 }
48 }
49 }
49
50
50 impl FromIterator<(Vec<u8>, DirstateEntry)> for DirstateMap {
51 impl FromIterator<(HgPathBuf, DirstateEntry)> for DirstateMap {
51 fn from_iter<I: IntoIterator<Item = (Vec<u8>, DirstateEntry)>>(
52 fn from_iter<I: IntoIterator<Item = (HgPathBuf, DirstateEntry)>>(
52 iter: I,
53 iter: I,
53 ) -> Self {
54 ) -> Self {
54 Self {
55 Self {
@@ -78,7 +79,7 b' impl DirstateMap {'
78 /// Add a tracked file to the dirstate
79 /// Add a tracked file to the dirstate
79 pub fn add_file(
80 pub fn add_file(
80 &mut self,
81 &mut self,
81 filename: &[u8],
82 filename: &HgPath,
82 old_state: EntryState,
83 old_state: EntryState,
83 entry: DirstateEntry,
84 entry: DirstateEntry,
84 ) {
85 ) {
@@ -111,7 +112,7 b' impl DirstateMap {'
111 /// to be more explicit about what that state is.
112 /// to be more explicit about what that state is.
112 pub fn remove_file(
113 pub fn remove_file(
113 &mut self,
114 &mut self,
114 filename: &[u8],
115 filename: &HgPath,
115 old_state: EntryState,
116 old_state: EntryState,
116 size: i32,
117 size: i32,
117 ) -> Result<(), DirstateMapError> {
118 ) -> Result<(), DirstateMapError> {
@@ -147,7 +148,7 b' impl DirstateMap {'
147 /// Returns `true` if the file was previously recorded.
148 /// Returns `true` if the file was previously recorded.
148 pub fn drop_file(
149 pub fn drop_file(
149 &mut self,
150 &mut self,
150 filename: &[u8],
151 filename: &HgPath,
151 old_state: EntryState,
152 old_state: EntryState,
152 ) -> Result<bool, DirstateMapError> {
153 ) -> Result<bool, DirstateMapError> {
153 let exists = self.state_map.remove(filename).is_some();
154 let exists = self.state_map.remove(filename).is_some();
@@ -172,7 +173,7 b' impl DirstateMap {'
172
173
173 pub fn clear_ambiguous_times(
174 pub fn clear_ambiguous_times(
174 &mut self,
175 &mut self,
175 filenames: Vec<Vec<u8>>,
176 filenames: Vec<HgPathBuf>,
176 now: i32,
177 now: i32,
177 ) {
178 ) {
178 for filename in filenames {
179 for filename in filenames {
@@ -197,7 +198,7 b' impl DirstateMap {'
197
198
198 pub fn non_normal_other_parent_entries(
199 pub fn non_normal_other_parent_entries(
199 &self,
200 &self,
200 ) -> (HashSet<Vec<u8>>, HashSet<Vec<u8>>) {
201 ) -> (HashSet<HgPathBuf>, HashSet<HgPathBuf>) {
201 let mut non_normal = HashSet::new();
202 let mut non_normal = HashSet::new();
202 let mut other_parent = HashSet::new();
203 let mut other_parent = HashSet::new();
203
204
@@ -239,12 +240,12 b' impl DirstateMap {'
239 }
240 }
240 }
241 }
241
242
242 pub fn has_tracked_dir(&mut self, directory: &[u8]) -> bool {
243 pub fn has_tracked_dir(&mut self, directory: &HgPath) -> bool {
243 self.set_dirs();
244 self.set_dirs();
244 self.dirs.as_ref().unwrap().contains(directory)
245 self.dirs.as_ref().unwrap().contains(directory)
245 }
246 }
246
247
247 pub fn has_dir(&mut self, directory: &[u8]) -> bool {
248 pub fn has_dir(&mut self, directory: &HgPath) -> bool {
248 self.set_all_dirs();
249 self.set_all_dirs();
249 self.all_dirs.as_ref().unwrap().contains(directory)
250 self.all_dirs.as_ref().unwrap().contains(directory)
250 }
251 }
@@ -346,11 +347,11 b' mod tests {'
346 assert!(map.dirs.is_none());
347 assert!(map.dirs.is_none());
347 assert!(map.all_dirs.is_none());
348 assert!(map.all_dirs.is_none());
348
349
349 assert_eq!(false, map.has_dir(b"nope"));
350 assert_eq!(false, map.has_dir(HgPath::new(b"nope")));
350 assert!(map.all_dirs.is_some());
351 assert!(map.all_dirs.is_some());
351 assert!(map.dirs.is_none());
352 assert!(map.dirs.is_none());
352
353
353 assert_eq!(false, map.has_tracked_dir(b"nope"));
354 assert_eq!(false, map.has_tracked_dir(HgPath::new(b"nope")));
354 assert!(map.dirs.is_some());
355 assert!(map.dirs.is_some());
355 }
356 }
356
357
@@ -361,7 +362,7 b' mod tests {'
361 assert_eq!(0, map.len());
362 assert_eq!(0, map.len());
362
363
363 map.add_file(
364 map.add_file(
364 b"meh",
365 HgPath::new(b"meh"),
365 EntryState::Normal,
366 EntryState::Normal,
366 DirstateEntry {
367 DirstateEntry {
367 state: EntryState::Normal,
368 state: EntryState::Normal,
@@ -394,7 +395,7 b' mod tests {'
394 .iter()
395 .iter()
395 .map(|(fname, (state, mode, size, mtime))| {
396 .map(|(fname, (state, mode, size, mtime))| {
396 (
397 (
397 fname.to_vec(),
398 HgPathBuf::from_bytes(fname.as_ref()),
398 DirstateEntry {
399 DirstateEntry {
399 state: *state,
400 state: *state,
400 mode: *mode,
401 mode: *mode,
@@ -409,11 +410,11 b' mod tests {'
409 b"f1", b"f2", b"f5", b"f6", b"f7", b"f8", b"f9", b"fa", b"fb",
410 b"f1", b"f2", b"f5", b"f6", b"f7", b"f8", b"f9", b"fa", b"fb",
410 ]
411 ]
411 .iter()
412 .iter()
412 .map(|x| x.to_vec())
413 .map(|x| HgPathBuf::from_bytes(x.as_ref()))
413 .collect();
414 .collect();
414
415
415 let mut other_parent = HashSet::new();
416 let mut other_parent = HashSet::new();
416 other_parent.insert(b"f4".to_vec());
417 other_parent.insert(HgPathBuf::from_bytes(b"f4"));
417
418
418 assert_eq!(
419 assert_eq!(
419 (non_normal, other_parent),
420 (non_normal, other_parent),
@@ -3,6 +3,7 b''
3 // This software may be used and distributed according to the terms of the
3 // This software may be used and distributed according to the terms of the
4 // GNU General Public License version 2 or any later version.
4 // GNU General Public License version 2 or any later version.
5
5
6 use crate::utils::hg_path::HgPath;
6 use crate::{
7 use crate::{
7 dirstate::{CopyMap, EntryState, StateMap},
8 dirstate::{CopyMap, EntryState, StateMap},
8 DirstateEntry, DirstatePackError, DirstateParents, DirstateParseError,
9 DirstateEntry, DirstatePackError, DirstateParents, DirstateParseError,
@@ -60,10 +61,13 b' pub fn parse_dirstate('
60 };
61 };
61
62
62 if let Some(copy_path) = copy {
63 if let Some(copy_path) = copy {
63 copy_map.insert(path.to_owned(), copy_path.to_owned());
64 copy_map.insert(
65 HgPath::new(path).to_owned(),
66 HgPath::new(copy_path).to_owned(),
67 );
64 };
68 };
65 state_map.insert(
69 state_map.insert(
66 path.to_owned(),
70 HgPath::new(path).to_owned(),
67 DirstateEntry {
71 DirstateEntry {
68 state,
72 state,
69 mode,
73 mode,
@@ -106,7 +110,7 b' pub fn pack_dirstate('
106 packed.extend(&parents.p2);
110 packed.extend(&parents.p2);
107
111
108 for (filename, entry) in state_map.iter() {
112 for (filename, entry) in state_map.iter() {
109 let mut new_filename: Vec<u8> = filename.to_owned();
113 let new_filename = filename.to_owned();
110 let mut new_mtime: i32 = entry.mtime;
114 let mut new_mtime: i32 = entry.mtime;
111 if entry.state == EntryState::Normal && entry.mtime == now {
115 if entry.state == EntryState::Normal && entry.mtime == now {
112 // The file was last modified "simultaneously" with the current
116 // The file was last modified "simultaneously" with the current
@@ -127,10 +131,10 b' pub fn pack_dirstate('
127 },
131 },
128 ));
132 ));
129 }
133 }
130
134 let mut new_filename = new_filename.into_vec();
131 if let Some(copy) = copy_map.get(filename) {
135 if let Some(copy) = copy_map.get(filename) {
132 new_filename.push('\0' as u8);
136 new_filename.push('\0' as u8);
133 new_filename.extend(copy);
137 new_filename.extend(copy.bytes());
134 }
138 }
135
139
136 packed.write_u8(entry.state.into())?;
140 packed.write_u8(entry.state.into())?;
@@ -153,6 +157,7 b' pub fn pack_dirstate('
153 #[cfg(test)]
157 #[cfg(test)]
154 mod tests {
158 mod tests {
155 use super::*;
159 use super::*;
160 use crate::utils::hg_path::HgPathBuf;
156 use std::collections::HashMap;
161 use std::collections::HashMap;
157
162
158 #[test]
163 #[test]
@@ -176,7 +181,7 b' mod tests {'
176 #[test]
181 #[test]
177 fn test_pack_dirstate_one_entry() {
182 fn test_pack_dirstate_one_entry() {
178 let expected_state_map: StateMap = [(
183 let expected_state_map: StateMap = [(
179 b"f1".to_vec(),
184 HgPathBuf::from_bytes(b"f1"),
180 DirstateEntry {
185 DirstateEntry {
181 state: EntryState::Normal,
186 state: EntryState::Normal,
182 mode: 0o644,
187 mode: 0o644,
@@ -213,7 +218,7 b' mod tests {'
213 #[test]
218 #[test]
214 fn test_pack_dirstate_one_entry_with_copy() {
219 fn test_pack_dirstate_one_entry_with_copy() {
215 let expected_state_map: StateMap = [(
220 let expected_state_map: StateMap = [(
216 b"f1".to_vec(),
221 HgPathBuf::from_bytes(b"f1"),
217 DirstateEntry {
222 DirstateEntry {
218 state: EntryState::Normal,
223 state: EntryState::Normal,
219 mode: 0o644,
224 mode: 0o644,
@@ -226,7 +231,10 b' mod tests {'
226 .collect();
231 .collect();
227 let mut state_map = expected_state_map.clone();
232 let mut state_map = expected_state_map.clone();
228 let mut copymap = HashMap::new();
233 let mut copymap = HashMap::new();
229 copymap.insert(b"f1".to_vec(), b"copyname".to_vec());
234 copymap.insert(
235 HgPathBuf::from_bytes(b"f1"),
236 HgPathBuf::from_bytes(b"copyname"),
237 );
230 let parents = DirstateParents {
238 let parents = DirstateParents {
231 p1: *b"12345678910111213141",
239 p1: *b"12345678910111213141",
232 p2: *b"00000000000000000000",
240 p2: *b"00000000000000000000",
@@ -251,7 +259,7 b' mod tests {'
251 #[test]
259 #[test]
252 fn test_parse_pack_one_entry_with_copy() {
260 fn test_parse_pack_one_entry_with_copy() {
253 let mut state_map: StateMap = [(
261 let mut state_map: StateMap = [(
254 b"f1".to_vec(),
262 HgPathBuf::from_bytes(b"f1"),
255 DirstateEntry {
263 DirstateEntry {
256 state: EntryState::Normal,
264 state: EntryState::Normal,
257 mode: 0o644,
265 mode: 0o644,
@@ -263,7 +271,10 b' mod tests {'
263 .cloned()
271 .cloned()
264 .collect();
272 .collect();
265 let mut copymap = HashMap::new();
273 let mut copymap = HashMap::new();
266 copymap.insert(b"f1".to_vec(), b"copyname".to_vec());
274 copymap.insert(
275 HgPathBuf::from_bytes(b"f1"),
276 HgPathBuf::from_bytes(b"copyname"),
277 );
267 let parents = DirstateParents {
278 let parents = DirstateParents {
268 p1: *b"12345678910111213141",
279 p1: *b"12345678910111213141",
269 p2: *b"00000000000000000000",
280 p2: *b"00000000000000000000",
@@ -291,7 +302,7 b' mod tests {'
291 fn test_parse_pack_multiple_entries_with_copy() {
302 fn test_parse_pack_multiple_entries_with_copy() {
292 let mut state_map: StateMap = [
303 let mut state_map: StateMap = [
293 (
304 (
294 b"f1".to_vec(),
305 HgPathBuf::from_bytes(b"f1"),
295 DirstateEntry {
306 DirstateEntry {
296 state: EntryState::Normal,
307 state: EntryState::Normal,
297 mode: 0o644,
308 mode: 0o644,
@@ -300,7 +311,7 b' mod tests {'
300 },
311 },
301 ),
312 ),
302 (
313 (
303 b"f2".to_vec(),
314 HgPathBuf::from_bytes(b"f2"),
304 DirstateEntry {
315 DirstateEntry {
305 state: EntryState::Merged,
316 state: EntryState::Merged,
306 mode: 0o777,
317 mode: 0o777,
@@ -309,7 +320,7 b' mod tests {'
309 },
320 },
310 ),
321 ),
311 (
322 (
312 b"f3".to_vec(),
323 HgPathBuf::from_bytes(b"f3"),
313 DirstateEntry {
324 DirstateEntry {
314 state: EntryState::Removed,
325 state: EntryState::Removed,
315 mode: 0o644,
326 mode: 0o644,
@@ -318,7 +329,7 b' mod tests {'
318 },
329 },
319 ),
330 ),
320 (
331 (
321 b"f4\xF6".to_vec(),
332 HgPathBuf::from_bytes(b"f4\xF6"),
322 DirstateEntry {
333 DirstateEntry {
323 state: EntryState::Added,
334 state: EntryState::Added,
324 mode: 0o644,
335 mode: 0o644,
@@ -331,8 +342,14 b' mod tests {'
331 .cloned()
342 .cloned()
332 .collect();
343 .collect();
333 let mut copymap = HashMap::new();
344 let mut copymap = HashMap::new();
334 copymap.insert(b"f1".to_vec(), b"copyname".to_vec());
345 copymap.insert(
335 copymap.insert(b"f4\xF6".to_vec(), b"copyname2".to_vec());
346 HgPathBuf::from_bytes(b"f1"),
347 HgPathBuf::from_bytes(b"copyname"),
348 );
349 copymap.insert(
350 HgPathBuf::from_bytes(b"f4\xF6"),
351 HgPathBuf::from_bytes(b"copyname2"),
352 );
336 let parents = DirstateParents {
353 let parents = DirstateParents {
337 p1: *b"12345678910111213141",
354 p1: *b"12345678910111213141",
338 p2: *b"00000000000000000000",
355 p2: *b"00000000000000000000",
@@ -360,7 +377,7 b' mod tests {'
360 /// https://www.mercurial-scm.org/repo/hg/rev/af3f26b6bba4
377 /// https://www.mercurial-scm.org/repo/hg/rev/af3f26b6bba4
361 fn test_parse_pack_one_entry_with_copy_and_time_conflict() {
378 fn test_parse_pack_one_entry_with_copy_and_time_conflict() {
362 let mut state_map: StateMap = [(
379 let mut state_map: StateMap = [(
363 b"f1".to_vec(),
380 HgPathBuf::from_bytes(b"f1"),
364 DirstateEntry {
381 DirstateEntry {
365 state: EntryState::Normal,
382 state: EntryState::Normal,
366 mode: 0o644,
383 mode: 0o644,
@@ -372,7 +389,10 b' mod tests {'
372 .cloned()
389 .cloned()
373 .collect();
390 .collect();
374 let mut copymap = HashMap::new();
391 let mut copymap = HashMap::new();
375 copymap.insert(b"f1".to_vec(), b"copyname".to_vec());
392 copymap.insert(
393 HgPathBuf::from_bytes(b"f1"),
394 HgPathBuf::from_bytes(b"copyname"),
395 );
376 let parents = DirstateParents {
396 let parents = DirstateParents {
377 p1: *b"12345678910111213141",
397 p1: *b"12345678910111213141",
378 p2: *b"00000000000000000000",
398 p2: *b"00000000000000000000",
@@ -395,7 +415,7 b' mod tests {'
395 (
415 (
396 parents,
416 parents,
397 [(
417 [(
398 b"f1".to_vec(),
418 HgPathBuf::from_bytes(b"f1"),
399 DirstateEntry {
419 DirstateEntry {
400 state: EntryState::Normal,
420 state: EntryState::Normal,
401 mode: 0o644,
421 mode: 0o644,
@@ -7,15 +7,13 b''
7
7
8 //! Handling of Mercurial-specific patterns.
8 //! Handling of Mercurial-specific patterns.
9
9
10 use crate::{
10 use crate::{utils::SliceExt, LineNumber, PatternError, PatternFileError};
11 utils::{files::get_path_from_bytes, SliceExt},
12 LineNumber, PatternError, PatternFileError,
13 };
14 use lazy_static::lazy_static;
11 use lazy_static::lazy_static;
15 use regex::bytes::{NoExpand, Regex};
12 use regex::bytes::{NoExpand, Regex};
16 use std::collections::HashMap;
13 use std::collections::HashMap;
17 use std::fs::File;
14 use std::fs::File;
18 use std::io::Read;
15 use std::io::Read;
16 use std::path::{Path, PathBuf};
19 use std::vec::Vec;
17 use std::vec::Vec;
20
18
21 lazy_static! {
19 lazy_static! {
@@ -230,11 +228,11 b' lazy_static! {'
230 }
228 }
231
229
232 pub type PatternTuple = (Vec<u8>, LineNumber, Vec<u8>);
230 pub type PatternTuple = (Vec<u8>, LineNumber, Vec<u8>);
233 type WarningTuple = (Vec<u8>, Vec<u8>);
231 type WarningTuple = (PathBuf, Vec<u8>);
234
232
235 pub fn parse_pattern_file_contents(
233 pub fn parse_pattern_file_contents<P: AsRef<Path>>(
236 lines: &[u8],
234 lines: &[u8],
237 file_path: &[u8],
235 file_path: P,
238 warn: bool,
236 warn: bool,
239 ) -> (Vec<PatternTuple>, Vec<WarningTuple>) {
237 ) -> (Vec<PatternTuple>, Vec<WarningTuple>) {
240 let comment_regex = Regex::new(r"((?:^|[^\\])(?:\\\\)*)#.*").unwrap();
238 let comment_regex = Regex::new(r"((?:^|[^\\])(?:\\\\)*)#.*").unwrap();
@@ -268,7 +266,8 b' pub fn parse_pattern_file_contents('
268 if let Some(rel_syntax) = SYNTAXES.get(syntax) {
266 if let Some(rel_syntax) = SYNTAXES.get(syntax) {
269 current_syntax = rel_syntax;
267 current_syntax = rel_syntax;
270 } else if warn {
268 } else if warn {
271 warnings.push((file_path.to_owned(), syntax.to_owned()));
269 warnings
270 .push((file_path.as_ref().to_owned(), syntax.to_owned()));
272 }
271 }
273 continue;
272 continue;
274 }
273 }
@@ -297,11 +296,11 b' pub fn parse_pattern_file_contents('
297 (inputs, warnings)
296 (inputs, warnings)
298 }
297 }
299
298
300 pub fn read_pattern_file(
299 pub fn read_pattern_file<P: AsRef<Path>>(
301 file_path: &[u8],
300 file_path: P,
302 warn: bool,
301 warn: bool,
303 ) -> Result<(Vec<PatternTuple>, Vec<WarningTuple>), PatternFileError> {
302 ) -> Result<(Vec<PatternTuple>, Vec<WarningTuple>), PatternFileError> {
304 let mut f = File::open(get_path_from_bytes(file_path))?;
303 let mut f = File::open(file_path.as_ref())?;
305 let mut contents = Vec::new();
304 let mut contents = Vec::new();
306
305
307 f.read_to_end(&mut contents)?;
306 f.read_to_end(&mut contents)?;
@@ -343,18 +342,21 b' mod tests {'
343
342
344 assert_eq!(
343 assert_eq!(
345 vec![(b"relglob:*.elc".to_vec(), 2, b"*.elc".to_vec())],
344 vec![(b"relglob:*.elc".to_vec(), 2, b"*.elc".to_vec())],
346 parse_pattern_file_contents(lines, b"file_path", false).0,
345 parse_pattern_file_contents(lines, Path::new("file_path"), false)
346 .0,
347 );
347 );
348
348
349 let lines = b"syntax: include\nsyntax: glob";
349 let lines = b"syntax: include\nsyntax: glob";
350
350
351 assert_eq!(
351 assert_eq!(
352 parse_pattern_file_contents(lines, b"file_path", false).0,
352 parse_pattern_file_contents(lines, Path::new("file_path"), false)
353 .0,
353 vec![]
354 vec![]
354 );
355 );
355 let lines = b"glob:**.o";
356 let lines = b"glob:**.o";
356 assert_eq!(
357 assert_eq!(
357 parse_pattern_file_contents(lines, b"file_path", false).0,
358 parse_pattern_file_contents(lines, Path::new("file_path"), false)
359 .0,
358 vec![(b"relglob:**.o".to_vec(), 1, b"**.o".to_vec())]
360 vec![(b"relglob:**.o".to_vec(), 1, b"**.o".to_vec())]
359 );
361 );
360 }
362 }
@@ -18,6 +18,7 b' pub use dirstate::{'
18 mod filepatterns;
18 mod filepatterns;
19 pub mod utils;
19 pub mod utils;
20
20
21 use crate::utils::hg_path::HgPathBuf;
21 pub use filepatterns::{
22 pub use filepatterns::{
22 build_single_regex, read_pattern_file, PatternSyntax, PatternTuple,
23 build_single_regex, read_pattern_file, PatternSyntax, PatternTuple,
23 };
24 };
@@ -96,7 +97,7 b' impl From<std::io::Error> for DirstatePa'
96 }
97 }
97 #[derive(Debug, PartialEq)]
98 #[derive(Debug, PartialEq)]
98 pub enum DirstateMapError {
99 pub enum DirstateMapError {
99 PathNotFound(Vec<u8>),
100 PathNotFound(HgPathBuf),
100 EmptyPath,
101 EmptyPath,
101 }
102 }
102
103
@@ -9,7 +9,9 b''
9
9
10 //! Functions for fiddling with files.
10 //! Functions for fiddling with files.
11
11
12 use crate::utils::hg_path::{HgPath, HgPathBuf};
12 use std::iter::FusedIterator;
13 use std::iter::FusedIterator;
14
13 use std::path::Path;
15 use std::path::Path;
14
16
15 pub fn get_path_from_bytes(bytes: &[u8]) -> &Path {
17 pub fn get_path_from_bytes(bytes: &[u8]) -> &Path {
@@ -23,8 +25,7 b' pub fn get_path_from_bytes(bytes: &[u8])'
23 {
25 {
24 // TODO: convert from Windows MBCS (ANSI encoding) to WTF8.
26 // TODO: convert from Windows MBCS (ANSI encoding) to WTF8.
25 // Perhaps, the return type would have to be Result<PathBuf>.
27 // Perhaps, the return type would have to be Result<PathBuf>.
26 use std::os::windows::ffi::OsStrExt;
28 unimplemented!()
27 os_str = std::ffi::OsString::from_wide(bytes);
28 }
29 }
29
30
30 Path::new(os_str)
31 Path::new(os_str)
@@ -33,20 +34,19 b' pub fn get_path_from_bytes(bytes: &[u8])'
33 /// An iterator over repository path yielding itself and its ancestors.
34 /// An iterator over repository path yielding itself and its ancestors.
34 #[derive(Copy, Clone, Debug)]
35 #[derive(Copy, Clone, Debug)]
35 pub struct Ancestors<'a> {
36 pub struct Ancestors<'a> {
36 next: Option<&'a [u8]>,
37 next: Option<&'a HgPath>,
37 }
38 }
38
39
39 impl<'a> Iterator for Ancestors<'a> {
40 impl<'a> Iterator for Ancestors<'a> {
40 // if we had an HgPath type, this would yield &'a HgPath
41 type Item = &'a HgPath;
41 type Item = &'a [u8];
42
42
43 fn next(&mut self) -> Option<Self::Item> {
43 fn next(&mut self) -> Option<Self::Item> {
44 let next = self.next;
44 let next = self.next;
45 self.next = match self.next {
45 self.next = match self.next {
46 Some(s) if s.is_empty() => None,
46 Some(s) if s.is_empty() => None,
47 Some(s) => {
47 Some(s) => {
48 let p = s.iter().rposition(|&c| c == b'/').unwrap_or(0);
48 let p = s.bytes().rposition(|c| *c == b'/').unwrap_or(0);
49 Some(&s[..p])
49 Some(HgPath::new(&s.as_bytes()[..p]))
50 }
50 }
51 None => None,
51 None => None,
52 };
52 };
@@ -63,7 +63,7 b" impl<'a> FusedIterator for Ancestors<'a>"
63 ///
63 ///
64 /// The path itself isn't included unless it is b"" (meaning the root
64 /// The path itself isn't included unless it is b"" (meaning the root
65 /// directory.)
65 /// directory.)
66 pub fn find_dirs<'a>(path: &'a [u8]) -> Ancestors<'a> {
66 pub fn find_dirs<'a>(path: &'a HgPath) -> Ancestors<'a> {
67 let mut dirs = Ancestors { next: Some(path) };
67 let mut dirs = Ancestors { next: Some(path) };
68 if !path.is_empty() {
68 if !path.is_empty() {
69 dirs.next(); // skip itself
69 dirs.next(); // skip itself
@@ -71,23 +71,24 b" pub fn find_dirs<'a>(path: &'a [u8]) -> "
71 dirs
71 dirs
72 }
72 }
73
73
74 /// TODO improve handling of utf8 file names. Our overall strategy for
74 /// TODO more than ASCII?
75 /// filenames has to be revisited anyway, since Windows is UTF-16.
75 pub fn normalize_case(path: &HgPath) -> HgPathBuf {
76 pub fn normalize_case(bytes: &[u8]) -> Vec<u8> {
77 #[cfg(windows)] // NTFS compares via upper()
76 #[cfg(windows)] // NTFS compares via upper()
78 return bytes.to_ascii_uppercase();
77 return path.to_ascii_uppercase();
79 #[cfg(unix)]
78 #[cfg(unix)]
80 bytes.to_ascii_lowercase()
79 path.to_ascii_lowercase()
81 }
80 }
82
81
83 #[cfg(test)]
82 #[cfg(test)]
84 mod tests {
83 mod tests {
84 use super::*;
85
85 #[test]
86 #[test]
86 fn find_dirs_some() {
87 fn find_dirs_some() {
87 let mut dirs = super::find_dirs(b"foo/bar/baz");
88 let mut dirs = super::find_dirs(HgPath::new(b"foo/bar/baz"));
88 assert_eq!(dirs.next(), Some(b"foo/bar".as_ref()));
89 assert_eq!(dirs.next(), Some(HgPath::new(b"foo/bar")));
89 assert_eq!(dirs.next(), Some(b"foo".as_ref()));
90 assert_eq!(dirs.next(), Some(HgPath::new(b"foo")));
90 assert_eq!(dirs.next(), Some(b"".as_ref()));
91 assert_eq!(dirs.next(), Some(HgPath::new(b"")));
91 assert_eq!(dirs.next(), None);
92 assert_eq!(dirs.next(), None);
92 assert_eq!(dirs.next(), None);
93 assert_eq!(dirs.next(), None);
93 }
94 }
@@ -95,8 +96,8 b' mod tests {'
95 #[test]
96 #[test]
96 fn find_dirs_empty() {
97 fn find_dirs_empty() {
97 // looks weird, but mercurial.util.finddirs(b"") yields b""
98 // looks weird, but mercurial.util.finddirs(b"") yields b""
98 let mut dirs = super::find_dirs(b"");
99 let mut dirs = super::find_dirs(HgPath::new(b""));
99 assert_eq!(dirs.next(), Some(b"".as_ref()));
100 assert_eq!(dirs.next(), Some(HgPath::new(b"")));
100 assert_eq!(dirs.next(), None);
101 assert_eq!(dirs.next(), None);
101 assert_eq!(dirs.next(), None);
102 assert_eq!(dirs.next(), None);
102 }
103 }
@@ -17,7 +17,10 b' use cpython::{'
17 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
17 exc, PyBytes, PyDict, PyErr, PyModule, PyObject, PyResult, PySequence,
18 Python,
18 Python,
19 };
19 };
20 use hg::{DirstateEntry, DirstateParseError, EntryState, StateMap};
20 use hg::{
21 utils::hg_path::HgPathBuf, DirstateEntry, DirstateParseError, EntryState,
22 StateMap,
23 };
21 use libc::{c_char, c_int};
24 use libc::{c_char, c_int};
22 #[cfg(feature = "python27")]
25 #[cfg(feature = "python27")]
23 use python27_sys::PyCapsule_Import;
26 use python27_sys::PyCapsule_Import;
@@ -75,7 +78,7 b' pub fn extract_dirstate(py: Python, dmap'
75 let filename = filename.extract::<PyBytes>(py)?;
78 let filename = filename.extract::<PyBytes>(py)?;
76 let filename = filename.data(py);
79 let filename = filename.data(py);
77 Ok((
80 Ok((
78 filename.to_owned(),
81 HgPathBuf::from(filename.to_owned()),
79 DirstateEntry {
82 DirstateEntry {
80 state,
83 state,
81 mode,
84 mode,
@@ -12,7 +12,7 b' use cpython::{PyBytes, PyClone, PyDict, '
12 use std::cell::RefCell;
12 use std::cell::RefCell;
13
13
14 use crate::dirstate::dirstate_map::{DirstateMap, DirstateMapLeakedRef};
14 use crate::dirstate::dirstate_map::{DirstateMap, DirstateMapLeakedRef};
15 use hg::CopyMapIter;
15 use hg::{utils::hg_path::HgPathBuf, CopyMapIter};
16
16
17 py_class!(pub class CopyMap |py| {
17 py_class!(pub class CopyMap |py| {
18 data dirstate_map: DirstateMap;
18 data dirstate_map: DirstateMap;
@@ -85,16 +85,19 b' impl CopyMap {'
85 }
85 }
86 fn translate_key(
86 fn translate_key(
87 py: Python,
87 py: Python,
88 res: (&Vec<u8>, &Vec<u8>),
88 res: (&HgPathBuf, &HgPathBuf),
89 ) -> PyResult<Option<PyBytes>> {
89 ) -> PyResult<Option<PyBytes>> {
90 Ok(Some(PyBytes::new(py, res.0)))
90 Ok(Some(PyBytes::new(py, res.0.as_ref())))
91 }
91 }
92 fn translate_key_value(
92 fn translate_key_value(
93 py: Python,
93 py: Python,
94 res: (&Vec<u8>, &Vec<u8>),
94 res: (&HgPathBuf, &HgPathBuf),
95 ) -> PyResult<Option<(PyBytes, PyBytes)>> {
95 ) -> PyResult<Option<(PyBytes, PyBytes)>> {
96 let (k, v) = res;
96 let (k, v) = res;
97 Ok(Some((PyBytes::new(py, k), PyBytes::new(py, v))))
97 Ok(Some((
98 PyBytes::new(py, k.as_ref()),
99 PyBytes::new(py, v.as_ref()),
100 )))
98 }
101 }
99 }
102 }
100
103
@@ -16,9 +16,12 b' use cpython::{'
16 Python,
16 Python,
17 };
17 };
18
18
19 use crate::dirstate::extract_dirstate;
19 use crate::{
20 use crate::ref_sharing::{PySharedRefCell, PySharedState};
20 dirstate::extract_dirstate,
21 ref_sharing::{PySharedRefCell, PySharedState},
22 };
21 use hg::{
23 use hg::{
24 utils::hg_path::{HgPath, HgPathBuf},
22 DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError,
25 DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError,
23 EntryState,
26 EntryState,
24 };
27 };
@@ -48,9 +51,13 b' py_class!(pub class Dirs |py| {'
48 let dirstate = extract_dirstate(py, &map)?;
51 let dirstate = extract_dirstate(py, &map)?;
49 DirsMultiset::from_dirstate(&dirstate, skip_state)
52 DirsMultiset::from_dirstate(&dirstate, skip_state)
50 } else {
53 } else {
51 let map: Result<Vec<Vec<u8>>, PyErr> = map
54 let map: Result<Vec<HgPathBuf>, PyErr> = map
52 .iter(py)?
55 .iter(py)?
53 .map(|o| Ok(o?.extract::<PyBytes>(py)?.data(py).to_owned()))
56 .map(|o| {
57 Ok(HgPathBuf::from_bytes(
58 o?.extract::<PyBytes>(py)?.data(py),
59 ))
60 })
54 .collect();
61 .collect();
55 DirsMultiset::from_manifest(&map?)
62 DirsMultiset::from_manifest(&map?)
56 };
63 };
@@ -64,14 +71,14 b' py_class!(pub class Dirs |py| {'
64
71
65 def addpath(&self, path: PyObject) -> PyResult<PyObject> {
72 def addpath(&self, path: PyObject) -> PyResult<PyObject> {
66 self.borrow_mut(py)?.add_path(
73 self.borrow_mut(py)?.add_path(
67 path.extract::<PyBytes>(py)?.data(py),
74 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
68 );
75 );
69 Ok(py.None())
76 Ok(py.None())
70 }
77 }
71
78
72 def delpath(&self, path: PyObject) -> PyResult<PyObject> {
79 def delpath(&self, path: PyObject) -> PyResult<PyObject> {
73 self.borrow_mut(py)?.delete_path(
80 self.borrow_mut(py)?.delete_path(
74 path.extract::<PyBytes>(py)?.data(py),
81 HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
75 )
82 )
76 .and(Ok(py.None()))
83 .and(Ok(py.None()))
77 .or_else(|e| {
84 .or_else(|e| {
@@ -98,10 +105,9 b' py_class!(pub class Dirs |py| {'
98 }
105 }
99
106
100 def __contains__(&self, item: PyObject) -> PyResult<bool> {
107 def __contains__(&self, item: PyObject) -> PyResult<bool> {
101 Ok(self
108 Ok(self.inner(py).borrow().contains(HgPath::new(
102 .inner(py)
109 item.extract::<PyBytes>(py)?.data(py).as_ref(),
103 .borrow()
110 )))
104 .contains(item.extract::<PyBytes>(py)?.data(py).as_ref()))
105 }
111 }
106 });
112 });
107
113
@@ -116,8 +122,11 b' impl Dirs {'
116 )
122 )
117 }
123 }
118
124
119 fn translate_key(py: Python, res: &Vec<u8>) -> PyResult<Option<PyBytes>> {
125 fn translate_key(
120 Ok(Some(PyBytes::new(py, res)))
126 py: Python,
127 res: &HgPathBuf,
128 ) -> PyResult<Option<PyBytes>> {
129 Ok(Some(PyBytes::new(py, res.as_ref())))
121 }
130 }
122 }
131 }
123
132
@@ -24,6 +24,7 b' use crate::{'
24 ref_sharing::{PySharedRefCell, PySharedState},
24 ref_sharing::{PySharedRefCell, PySharedState},
25 };
25 };
26 use hg::{
26 use hg::{
27 utils::hg_path::{HgPath, HgPathBuf},
27 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
28 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
28 DirstateParents, DirstateParseError, EntryState, StateMapIter,
29 DirstateParents, DirstateParseError, EntryState, StateMapIter,
29 PARENT_SIZE,
30 PARENT_SIZE,
@@ -65,7 +66,7 b' py_class!(pub class DirstateMap |py| {'
65 default: Option<PyObject> = None
66 default: Option<PyObject> = None
66 ) -> PyResult<Option<PyObject>> {
67 ) -> PyResult<Option<PyObject>> {
67 let key = key.extract::<PyBytes>(py)?;
68 let key = key.extract::<PyBytes>(py)?;
68 match self.inner(py).borrow().get(key.data(py)) {
69 match self.inner(py).borrow().get(HgPath::new(key.data(py))) {
69 Some(entry) => {
70 Some(entry) => {
70 // Explicitly go through u8 first, then cast to
71 // Explicitly go through u8 first, then cast to
71 // platform-specific `c_char`.
72 // platform-specific `c_char`.
@@ -91,7 +92,7 b' py_class!(pub class DirstateMap |py| {'
91 mtime: PyObject
92 mtime: PyObject
92 ) -> PyResult<PyObject> {
93 ) -> PyResult<PyObject> {
93 self.borrow_mut(py)?.add_file(
94 self.borrow_mut(py)?.add_file(
94 f.extract::<PyBytes>(py)?.data(py),
95 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
95 oldstate.extract::<PyBytes>(py)?.data(py)[0]
96 oldstate.extract::<PyBytes>(py)?.data(py)[0]
96 .try_into()
97 .try_into()
97 .map_err(|e: DirstateParseError| {
98 .map_err(|e: DirstateParseError| {
@@ -119,7 +120,7 b' py_class!(pub class DirstateMap |py| {'
119 ) -> PyResult<PyObject> {
120 ) -> PyResult<PyObject> {
120 self.borrow_mut(py)?
121 self.borrow_mut(py)?
121 .remove_file(
122 .remove_file(
122 f.extract::<PyBytes>(py)?.data(py),
123 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
123 oldstate.extract::<PyBytes>(py)?.data(py)[0]
124 oldstate.extract::<PyBytes>(py)?.data(py)[0]
124 .try_into()
125 .try_into()
125 .map_err(|e: DirstateParseError| {
126 .map_err(|e: DirstateParseError| {
@@ -143,7 +144,7 b' py_class!(pub class DirstateMap |py| {'
143 ) -> PyResult<PyBool> {
144 ) -> PyResult<PyBool> {
144 self.borrow_mut(py)?
145 self.borrow_mut(py)?
145 .drop_file(
146 .drop_file(
146 f.extract::<PyBytes>(py)?.data(py),
147 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
147 oldstate.extract::<PyBytes>(py)?.data(py)[0]
148 oldstate.extract::<PyBytes>(py)?.data(py)[0]
148 .try_into()
149 .try_into()
149 .map_err(|e: DirstateParseError| {
150 .map_err(|e: DirstateParseError| {
@@ -164,10 +165,12 b' py_class!(pub class DirstateMap |py| {'
164 files: PyObject,
165 files: PyObject,
165 now: PyObject
166 now: PyObject
166 ) -> PyResult<PyObject> {
167 ) -> PyResult<PyObject> {
167 let files: PyResult<Vec<Vec<u8>>> = files
168 let files: PyResult<Vec<HgPathBuf>> = files
168 .iter(py)?
169 .iter(py)?
169 .map(|filename| {
170 .map(|filename| {
170 Ok(filename?.extract::<PyBytes>(py)?.data(py).to_owned())
171 Ok(HgPathBuf::from_bytes(
172 filename?.extract::<PyBytes>(py)?.data(py),
173 ))
171 })
174 })
172 .collect();
175 .collect();
173 self.borrow_mut(py)?
176 self.borrow_mut(py)?
@@ -186,7 +189,7 b' py_class!(pub class DirstateMap |py| {'
186 "non_normal",
189 "non_normal",
187 non_normal
190 non_normal
188 .iter()
191 .iter()
189 .map(|v| PyBytes::new(py, &v))
192 .map(|v| PyBytes::new(py, v.as_ref()))
190 .collect::<Vec<PyBytes>>()
193 .collect::<Vec<PyBytes>>()
191 .to_py_object(py),
194 .to_py_object(py),
192 )?;
195 )?;
@@ -195,7 +198,7 b' py_class!(pub class DirstateMap |py| {'
195 "other_parent",
198 "other_parent",
196 other_parent
199 other_parent
197 .iter()
200 .iter()
198 .map(|v| PyBytes::new(py, &v))
201 .map(|v| PyBytes::new(py, v.as_ref()))
199 .collect::<Vec<PyBytes>>()
202 .collect::<Vec<PyBytes>>()
200 .to_py_object(py),
203 .to_py_object(py),
201 )?;
204 )?;
@@ -206,14 +209,14 b' py_class!(pub class DirstateMap |py| {'
206 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
209 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
207 let d = d.extract::<PyBytes>(py)?;
210 let d = d.extract::<PyBytes>(py)?;
208 Ok(self.borrow_mut(py)?
211 Ok(self.borrow_mut(py)?
209 .has_tracked_dir(d.data(py))
212 .has_tracked_dir(HgPath::new(d.data(py)))
210 .to_py_object(py))
213 .to_py_object(py))
211 }
214 }
212
215
213 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
216 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
214 let d = d.extract::<PyBytes>(py)?;
217 let d = d.extract::<PyBytes>(py)?;
215 Ok(self.borrow_mut(py)?
218 Ok(self.borrow_mut(py)?
216 .has_dir(d.data(py))
219 .has_dir(HgPath::new(d.data(py)))
217 .to_py_object(py))
220 .to_py_object(py))
218 }
221 }
219
222
@@ -280,10 +283,8 b' py_class!(pub class DirstateMap |py| {'
280
283
281 def filefoldmapasdict(&self) -> PyResult<PyDict> {
284 def filefoldmapasdict(&self) -> PyResult<PyDict> {
282 let dict = PyDict::new(py);
285 let dict = PyDict::new(py);
283 for (key, value) in
286 for (key, value) in self.borrow_mut(py)?.build_file_fold_map().iter() {
284 self.borrow_mut(py)?.build_file_fold_map().iter()
287 dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?;
285 {
286 dict.set_item(py, key, value)?;
287 }
288 }
288 Ok(dict)
289 Ok(dict)
289 }
290 }
@@ -294,12 +295,12 b' py_class!(pub class DirstateMap |py| {'
294
295
295 def __contains__(&self, key: PyObject) -> PyResult<bool> {
296 def __contains__(&self, key: PyObject) -> PyResult<bool> {
296 let key = key.extract::<PyBytes>(py)?;
297 let key = key.extract::<PyBytes>(py)?;
297 Ok(self.inner(py).borrow().contains_key(key.data(py)))
298 Ok(self.inner(py).borrow().contains_key(HgPath::new(key.data(py))))
298 }
299 }
299
300
300 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
301 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
301 let key = key.extract::<PyBytes>(py)?;
302 let key = key.extract::<PyBytes>(py)?;
302 let key = key.data(py);
303 let key = HgPath::new(key.data(py));
303 match self.inner(py).borrow().get(key) {
304 match self.inner(py).borrow().get(key) {
304 Some(entry) => {
305 Some(entry) => {
305 // Explicitly go through u8 first, then cast to
306 // Explicitly go through u8 first, then cast to
@@ -314,7 +315,7 b' py_class!(pub class DirstateMap |py| {'
314 },
315 },
315 None => Err(PyErr::new::<exc::KeyError, _>(
316 None => Err(PyErr::new::<exc::KeyError, _>(
316 py,
317 py,
317 String::from_utf8_lossy(key),
318 String::from_utf8_lossy(key.as_bytes()),
318 )),
319 )),
319 }
320 }
320 }
321 }
@@ -373,15 +374,19 b' py_class!(pub class DirstateMap |py| {'
373 def copymapcopy(&self) -> PyResult<PyDict> {
374 def copymapcopy(&self) -> PyResult<PyDict> {
374 let dict = PyDict::new(py);
375 let dict = PyDict::new(py);
375 for (key, value) in self.inner(py).borrow().copy_map.iter() {
376 for (key, value) in self.inner(py).borrow().copy_map.iter() {
376 dict.set_item(py, PyBytes::new(py, key), PyBytes::new(py, value))?;
377 dict.set_item(
378 py,
379 PyBytes::new(py, key.as_ref()),
380 PyBytes::new(py, value.as_ref()),
381 )?;
377 }
382 }
378 Ok(dict)
383 Ok(dict)
379 }
384 }
380
385
381 def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
386 def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
382 let key = key.extract::<PyBytes>(py)?;
387 let key = key.extract::<PyBytes>(py)?;
383 match self.inner(py).borrow().copy_map.get(key.data(py)) {
388 match self.inner(py).borrow().copy_map.get(HgPath::new(key.data(py))) {
384 Some(copy) => Ok(PyBytes::new(py, copy)),
389 Some(copy) => Ok(PyBytes::new(py, copy.as_ref())),
385 None => Err(PyErr::new::<exc::KeyError, _>(
390 None => Err(PyErr::new::<exc::KeyError, _>(
386 py,
391 py,
387 String::from_utf8_lossy(key.data(py)),
392 String::from_utf8_lossy(key.data(py)),
@@ -397,7 +402,11 b' py_class!(pub class DirstateMap |py| {'
397 }
402 }
398 def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
403 def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
399 let key = key.extract::<PyBytes>(py)?;
404 let key = key.extract::<PyBytes>(py)?;
400 Ok(self.inner(py).borrow().copy_map.contains_key(key.data(py)))
405 Ok(self
406 .inner(py)
407 .borrow()
408 .copy_map
409 .contains_key(HgPath::new(key.data(py))))
401 }
410 }
402 def copymapget(
411 def copymapget(
403 &self,
412 &self,
@@ -405,8 +414,15 b' py_class!(pub class DirstateMap |py| {'
405 default: Option<PyObject>
414 default: Option<PyObject>
406 ) -> PyResult<Option<PyObject>> {
415 ) -> PyResult<Option<PyObject>> {
407 let key = key.extract::<PyBytes>(py)?;
416 let key = key.extract::<PyBytes>(py)?;
408 match self.inner(py).borrow().copy_map.get(key.data(py)) {
417 match self
409 Some(copy) => Ok(Some(PyBytes::new(py, copy).into_object())),
418 .inner(py)
419 .borrow()
420 .copy_map
421 .get(HgPath::new(key.data(py)))
422 {
423 Some(copy) => Ok(Some(
424 PyBytes::new(py, copy.as_ref()).into_object(),
425 )),
410 None => Ok(default),
426 None => Ok(default),
411 }
427 }
412 }
428 }
@@ -417,9 +433,10 b' py_class!(pub class DirstateMap |py| {'
417 ) -> PyResult<PyObject> {
433 ) -> PyResult<PyObject> {
418 let key = key.extract::<PyBytes>(py)?;
434 let key = key.extract::<PyBytes>(py)?;
419 let value = value.extract::<PyBytes>(py)?;
435 let value = value.extract::<PyBytes>(py)?;
420 self.borrow_mut(py)?
436 self.borrow_mut(py)?.copy_map.insert(
421 .copy_map
437 HgPathBuf::from_bytes(key.data(py)),
422 .insert(key.data(py).to_vec(), value.data(py).to_vec());
438 HgPathBuf::from_bytes(value.data(py)),
439 );
423 Ok(py.None())
440 Ok(py.None())
424 }
441 }
425 def copymappop(
442 def copymappop(
@@ -428,7 +445,11 b' py_class!(pub class DirstateMap |py| {'
428 default: Option<PyObject>
445 default: Option<PyObject>
429 ) -> PyResult<Option<PyObject>> {
446 ) -> PyResult<Option<PyObject>> {
430 let key = key.extract::<PyBytes>(py)?;
447 let key = key.extract::<PyBytes>(py)?;
431 match self.borrow_mut(py)?.copy_map.remove(key.data(py)) {
448 match self
449 .borrow_mut(py)?
450 .copy_map
451 .remove(HgPath::new(key.data(py)))
452 {
432 Some(_) => Ok(None),
453 Some(_) => Ok(None),
433 None => Ok(default),
454 None => Ok(default),
434 }
455 }
@@ -457,13 +478,13 b' py_class!(pub class DirstateMap |py| {'
457 impl DirstateMap {
478 impl DirstateMap {
458 fn translate_key(
479 fn translate_key(
459 py: Python,
480 py: Python,
460 res: (&Vec<u8>, &DirstateEntry),
481 res: (&HgPathBuf, &DirstateEntry),
461 ) -> PyResult<Option<PyBytes>> {
482 ) -> PyResult<Option<PyBytes>> {
462 Ok(Some(PyBytes::new(py, res.0)))
483 Ok(Some(PyBytes::new(py, res.0.as_ref())))
463 }
484 }
464 fn translate_key_value(
485 fn translate_key_value(
465 py: Python,
486 py: Python,
466 res: (&Vec<u8>, &DirstateEntry),
487 res: (&HgPathBuf, &DirstateEntry),
467 ) -> PyResult<Option<(PyBytes, PyObject)>> {
488 ) -> PyResult<Option<(PyBytes, PyObject)>> {
468 let (f, entry) = res;
489 let (f, entry) = res;
469
490
@@ -471,7 +492,7 b' impl DirstateMap {'
471 // platform-specific `c_char`.
492 // platform-specific `c_char`.
472 let state: u8 = entry.state.into();
493 let state: u8 = entry.state.into();
473 Ok(Some((
494 Ok(Some((
474 PyBytes::new(py, f),
495 PyBytes::new(py, f.as_ref()),
475 decapsule_make_dirstate_tuple(py)?(
496 decapsule_make_dirstate_tuple(py)?(
476 state as c_char,
497 state as c_char,
477 entry.mode,
498 entry.mode,
@@ -41,6 +41,7 b' impl GraphError {'
41
41
42 py_exception!(rustext, PatternError, RuntimeError);
42 py_exception!(rustext, PatternError, RuntimeError);
43 py_exception!(rustext, PatternFileError, RuntimeError);
43 py_exception!(rustext, PatternFileError, RuntimeError);
44 py_exception!(rustext, HgPathPyError, RuntimeError);
44
45
45 impl PatternError {
46 impl PatternError {
46 pub fn pynew(py: Python, inner: hg::PatternError) -> PyErr {
47 pub fn pynew(py: Python, inner: hg::PatternError) -> PyErr {
@@ -13,9 +13,14 b''
13 //!
13 //!
14 use crate::exceptions::{PatternError, PatternFileError};
14 use crate::exceptions::{PatternError, PatternFileError};
15 use cpython::{
15 use cpython::{
16 PyBytes, PyDict, PyModule, PyObject, PyResult, PyTuple, Python, ToPyObject,
16 PyBytes, PyDict, PyModule, PyObject, PyResult, PyString, PyTuple, Python,
17 ToPyObject,
17 };
18 };
18 use hg::{build_single_regex, read_pattern_file, LineNumber, PatternTuple};
19 use hg::{
20 build_single_regex, read_pattern_file, utils::files::get_path_from_bytes,
21 LineNumber, PatternTuple,
22 };
23 use std::path::PathBuf;
19
24
20 /// Rust does not like functions with different return signatures.
25 /// Rust does not like functions with different return signatures.
21 /// The 3-tuple version is always returned by the hg-core function,
26 /// The 3-tuple version is always returned by the hg-core function,
@@ -33,7 +38,9 b' fn read_pattern_file_wrapper('
33 warn: bool,
38 warn: bool,
34 source_info: bool,
39 source_info: bool,
35 ) -> PyResult<PyTuple> {
40 ) -> PyResult<PyTuple> {
36 match read_pattern_file(file_path.extract::<PyBytes>(py)?.data(py), warn) {
41 let bytes = file_path.extract::<PyBytes>(py)?;
42 let path = get_path_from_bytes(bytes.data(py));
43 match read_pattern_file(path, warn) {
37 Ok((patterns, warnings)) => {
44 Ok((patterns, warnings)) => {
38 if source_info {
45 if source_info {
39 let itemgetter = |x: &PatternTuple| {
46 let itemgetter = |x: &PatternTuple| {
@@ -58,11 +65,16 b' fn read_pattern_file_wrapper('
58
65
59 fn warnings_to_py_bytes(
66 fn warnings_to_py_bytes(
60 py: Python,
67 py: Python,
61 warnings: &[(Vec<u8>, Vec<u8>)],
68 warnings: &[(PathBuf, Vec<u8>)],
62 ) -> Vec<(PyBytes, PyBytes)> {
69 ) -> Vec<(PyString, PyBytes)> {
63 warnings
70 warnings
64 .iter()
71 .iter()
65 .map(|(path, syn)| (PyBytes::new(py, path), PyBytes::new(py, syn)))
72 .map(|(path, syn)| {
73 (
74 PyString::new(py, &path.to_string_lossy()),
75 PyBytes::new(py, syn),
76 )
77 })
66 .collect()
78 .collect()
67 }
79 }
68
80
@@ -15,8 +15,8 b' use cpython::{'
15 PythonObject, ToPyObject,
15 PythonObject, ToPyObject,
16 };
16 };
17 use hg::{
17 use hg::{
18 pack_dirstate, parse_dirstate, DirstateEntry, DirstatePackError,
18 pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, DirstateEntry,
19 DirstateParents, DirstateParseError, PARENT_SIZE,
19 DirstatePackError, DirstateParents, DirstateParseError, PARENT_SIZE,
20 };
20 };
21 use std::collections::HashMap;
21 use std::collections::HashMap;
22 use std::convert::TryInto;
22 use std::convert::TryInto;
@@ -46,7 +46,7 b' fn parse_dirstate_wrapper('
46
46
47 dmap.set_item(
47 dmap.set_item(
48 py,
48 py,
49 PyBytes::new(py, &filename),
49 PyBytes::new(py, filename.as_ref()),
50 decapsule_make_dirstate_tuple(py)?(
50 decapsule_make_dirstate_tuple(py)?(
51 state as c_char,
51 state as c_char,
52 entry.mode,
52 entry.mode,
@@ -58,8 +58,8 b' fn parse_dirstate_wrapper('
58 for (path, copy_path) in copies {
58 for (path, copy_path) in copies {
59 copymap.set_item(
59 copymap.set_item(
60 py,
60 py,
61 PyBytes::new(py, &path),
61 PyBytes::new(py, path.as_ref()),
62 PyBytes::new(py, &copy_path),
62 PyBytes::new(py, copy_path.as_ref()),
63 )?;
63 )?;
64 }
64 }
65 Ok(
65 Ok(
@@ -99,13 +99,13 b' fn pack_dirstate_wrapper('
99
99
100 let mut dirstate_map = extract_dirstate(py, &dmap)?;
100 let mut dirstate_map = extract_dirstate(py, &dmap)?;
101
101
102 let copies: Result<HashMap<Vec<u8>, Vec<u8>>, PyErr> = copymap
102 let copies: Result<HashMap<HgPathBuf, HgPathBuf>, PyErr> = copymap
103 .items(py)
103 .items(py)
104 .iter()
104 .iter()
105 .map(|(key, value)| {
105 .map(|(key, value)| {
106 Ok((
106 Ok((
107 key.extract::<PyBytes>(py)?.data(py).to_owned(),
107 HgPathBuf::from_bytes(key.extract::<PyBytes>(py)?.data(py)),
108 value.extract::<PyBytes>(py)?.data(py).to_owned(),
108 HgPathBuf::from_bytes(value.extract::<PyBytes>(py)?.data(py)),
109 ))
109 ))
110 })
110 })
111 .collect();
111 .collect();
@@ -144,7 +144,7 b' fn pack_dirstate_wrapper('
144 let state: u8 = state.into();
144 let state: u8 = state.into();
145 dmap.set_item(
145 dmap.set_item(
146 py,
146 py,
147 PyBytes::new(py, &filename[..]),
147 PyBytes::new(py, filename.as_ref()),
148 decapsule_make_dirstate_tuple(py)?(
148 decapsule_make_dirstate_tuple(py)?(
149 state as c_char,
149 state as c_char,
150 mode,
150 mode,
General Comments 0
You need to be logged in to leave comments. Login now