33 .map_err(|_| HgError::corrupted("Too little data for dirstate."))?; |
33 .map_err(|_| HgError::corrupted("Too little data for dirstate."))?; |
34 Ok(parents) |
34 Ok(parents) |
35 } |
35 } |
36 |
36 |
37 #[timed] |
37 #[timed] |
38 pub fn parse_dirstate(mut contents: &[u8]) -> Result<ParseResult, HgError> { |
38 pub fn parse_dirstate(contents: &[u8]) -> Result<ParseResult, HgError> { |
39 let mut copies = Vec::new(); |
39 let mut copies = Vec::new(); |
40 let mut entries = Vec::new(); |
40 let mut entries = Vec::new(); |
41 |
41 let parents = |
|
42 parse_dirstate_entries(contents, |path, entry, copy_source| { |
|
43 if let Some(source) = copy_source { |
|
44 copies.push((path, source)); |
|
45 } |
|
46 entries.push((path, *entry)); |
|
47 })?; |
|
48 Ok((parents, entries, copies)) |
|
49 } |
|
50 |
|
51 pub fn parse_dirstate_entries<'a>( |
|
52 mut contents: &'a [u8], |
|
53 mut each_entry: impl FnMut(&'a HgPath, &DirstateEntry, Option<&'a HgPath>), |
|
54 ) -> Result<&'a DirstateParents, HgError> { |
42 let (parents, rest) = DirstateParents::from_bytes(contents) |
55 let (parents, rest) = DirstateParents::from_bytes(contents) |
43 .map_err(|_| HgError::corrupted("Too little data for dirstate."))?; |
56 .map_err(|_| HgError::corrupted("Too little data for dirstate."))?; |
44 contents = rest; |
57 contents = rest; |
45 while !contents.is_empty() { |
58 while !contents.is_empty() { |
46 let (raw_entry, rest) = RawEntry::from_bytes(contents) |
59 let (raw_entry, rest) = RawEntry::from_bytes(contents) |
60 // byte |
73 // byte |
61 let mut iter = paths.splitn(2, |&byte| byte == b'\0'); |
74 let mut iter = paths.splitn(2, |&byte| byte == b'\0'); |
62 let path = HgPath::new( |
75 let path = HgPath::new( |
63 iter.next().expect("splitn always yields at least one item"), |
76 iter.next().expect("splitn always yields at least one item"), |
64 ); |
77 ); |
65 if let Some(copy_source) = iter.next() { |
78 let copy_source = iter.next().map(HgPath::new); |
66 copies.push((path, HgPath::new(copy_source))); |
79 each_entry(path, &entry, copy_source); |
67 } |
80 |
68 |
|
69 entries.push((path, entry)); |
|
70 contents = rest; |
81 contents = rest; |
71 } |
82 } |
72 Ok((parents, entries, copies)) |
83 Ok(parents) |
73 } |
84 } |
74 |
85 |
75 /// `now` is the duration in seconds since the Unix epoch |
86 /// `now` is the duration in seconds since the Unix epoch |
76 pub fn pack_dirstate( |
87 pub fn pack_dirstate( |
77 state_map: &mut StateMap, |
88 state_map: &mut StateMap, |