comparison rust/hg-core/src/operations/cat.rs @ 48343:eb428010aad2

rhg: Also parse flags in the manifest parser Differential Revision: https://phab.mercurial-scm.org/D11772
author Simon Sapin <simon.sapin@octobus.net>
date Tue, 23 Nov 2021 19:39:51 +0100
parents 10c32e1b892a
children 20d0d896183e
comparison
equal deleted inserted replaced
48342:10c32e1b892a 48343:eb428010aad2
10 use crate::revlog::Node; 10 use crate::revlog::Node;
11 11
12 use crate::utils::hg_path::HgPath; 12 use crate::utils::hg_path::HgPath;
13 13
14 use crate::errors::HgError; 14 use crate::errors::HgError;
15 use crate::manifest::Manifest;
16 use crate::manifest::ManifestEntry;
15 use itertools::put_back; 17 use itertools::put_back;
16 use itertools::PutBack; 18 use itertools::PutBack;
17 use std::cmp::Ordering; 19 use std::cmp::Ordering;
18 20
19 pub struct CatOutput<'a> { 21 pub struct CatOutput<'a> {
27 /// The node ID that the given revset was resolved to 29 /// The node ID that the given revset was resolved to
28 pub node: Node, 30 pub node: Node,
29 } 31 }
30 32
31 // Find an item in an iterator over a sorted collection. 33 // Find an item in an iterator over a sorted collection.
32 fn find_item<'a, D, I: Iterator<Item = Result<(&'a HgPath, D), HgError>>>( 34 fn find_item<'a>(
33 i: &mut PutBack<I>, 35 i: &mut PutBack<impl Iterator<Item = Result<ManifestEntry<'a>, HgError>>>,
34 needle: &HgPath, 36 needle: &HgPath,
35 ) -> Result<Option<D>, HgError> { 37 ) -> Result<Option<Node>, HgError> {
36 loop { 38 loop {
37 match i.next() { 39 match i.next() {
38 None => return Ok(None), 40 None => return Ok(None),
39 Some(result) => { 41 Some(result) => {
40 let (path, value) = result?; 42 let entry = result?;
41 match needle.as_bytes().cmp(path.as_bytes()) { 43 match needle.as_bytes().cmp(entry.path.as_bytes()) {
42 Ordering::Less => { 44 Ordering::Less => {
43 i.put_back(Ok((path, value))); 45 i.put_back(Ok(entry));
44 return Ok(None); 46 return Ok(None);
45 } 47 }
46 Ordering::Greater => continue, 48 Ordering::Greater => continue,
47 Ordering::Equal => return Ok(Some(value)), 49 Ordering::Equal => return Ok(Some(entry.node_id()?)),
48 } 50 }
49 } 51 }
50 } 52 }
51 } 53 }
52 } 54 }
53 55
54 fn find_files_in_manifest< 56 fn find_files_in_manifest<'query>(
55 'manifest, 57 manifest: &Manifest,
56 'query, 58 query: impl Iterator<Item = &'query HgPath>,
57 Data, 59 ) -> Result<(Vec<(&'query HgPath, Node)>, Vec<&'query HgPath>), HgError> {
58 Manifest: Iterator<Item = Result<(&'manifest HgPath, Data), HgError>>, 60 let mut manifest = put_back(manifest.iter());
59 Query: Iterator<Item = &'query HgPath>,
60 >(
61 manifest: Manifest,
62 query: Query,
63 ) -> Result<(Vec<(&'query HgPath, Data)>, Vec<&'query HgPath>), HgError> {
64 let mut manifest = put_back(manifest);
65 let mut res = vec![]; 61 let mut res = vec![];
66 let mut missing = vec![]; 62 let mut missing = vec![];
67 63
68 for file in query { 64 for file in query {
69 match find_item(&mut manifest, file)? { 65 match find_item(&mut manifest, file)? {
94 let mut found_any = false; 90 let mut found_any = false;
95 91
96 files.sort_unstable(); 92 files.sort_unstable();
97 93
98 let (found, missing) = find_files_in_manifest( 94 let (found, missing) = find_files_in_manifest(
99 manifest.files_with_nodes(), 95 &manifest,
100 files.into_iter().map(|f| f.as_ref()), 96 files.into_iter().map(|f| f.as_ref()),
101 )?; 97 )?;
102 98
103 for (file_path, node_bytes) in found { 99 for (file_path, file_node) in found {
104 found_any = true; 100 found_any = true;
105 let file_log = repo.filelog(file_path)?; 101 let file_log = repo.filelog(file_path)?;
106 let file_node = Node::from_hex_for_repo(node_bytes)?;
107 results.push(( 102 results.push((
108 file_path, 103 file_path,
109 file_log.data_for_node(file_node)?.into_data()?, 104 file_log.data_for_node(file_node)?.into_data()?,
110 )); 105 ));
111 } 106 }