rust/hg-core/src/dirstate/parsers.rs
changeset 47097 e66ea29e2b1a
parent 46890 441024b279a6
child 47101 5d62243c7732
--- a/rust/hg-core/src/dirstate/parsers.rs	Thu Apr 08 20:12:24 2021 +0200
+++ b/rust/hg-core/src/dirstate/parsers.rs	Wed Mar 31 18:59:49 2021 +0200
@@ -35,10 +35,23 @@
 }
 
 #[timed]
-pub fn parse_dirstate(mut contents: &[u8]) -> Result<ParseResult, HgError> {
+pub fn parse_dirstate(contents: &[u8]) -> Result<ParseResult, HgError> {
     let mut copies = Vec::new();
     let mut entries = Vec::new();
+    let parents =
+        parse_dirstate_entries(contents, |path, entry, copy_source| {
+            if let Some(source) = copy_source {
+                copies.push((path, source));
+            }
+            entries.push((path, *entry));
+        })?;
+    Ok((parents, entries, copies))
+}
 
+pub fn parse_dirstate_entries<'a>(
+    mut contents: &'a [u8],
+    mut each_entry: impl FnMut(&'a HgPath, &DirstateEntry, Option<&'a HgPath>),
+) -> Result<&'a DirstateParents, HgError> {
     let (parents, rest) = DirstateParents::from_bytes(contents)
         .map_err(|_| HgError::corrupted("Too little data for dirstate."))?;
     contents = rest;
@@ -62,14 +75,12 @@
         let path = HgPath::new(
             iter.next().expect("splitn always yields at least one item"),
         );
-        if let Some(copy_source) = iter.next() {
-            copies.push((path, HgPath::new(copy_source)));
-        }
+        let copy_source = iter.next().map(HgPath::new);
+        each_entry(path, &entry, copy_source);
 
-        entries.push((path, entry));
         contents = rest;
     }
-    Ok((parents, entries, copies))
+    Ok(parents)
 }
 
 /// `now` is the duration in seconds since the Unix epoch