annotate rust/hg-core/src/revlog/filelog.rs @ 52760:94e2547e6f3d

rust: move code from utils to utils::strings This moves string-related functions in hg::utils into the recently added hg::utils::strings module.
author Mitchell Kember <mkember@janestreet.com>
date Thu, 16 Jan 2025 13:15:02 -0500
parents 5af65969edaf
children 37e9e6e1f470
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
1 use crate::errors::HgError;
50974
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
2 use crate::exit_codes;
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
3 use crate::repo::Repo;
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
4 use crate::revlog::path_encode::path_encode;
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
5 use crate::revlog::NodePrefix;
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
6 use crate::revlog::Revision;
49937
750409505286 rust-clippy: merge "revlog" module definition and struct implementation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
7 use crate::revlog::RevlogEntry;
750409505286 rust-clippy: merge "revlog" module definition and struct implementation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49930
diff changeset
8 use crate::revlog::{Revlog, RevlogError};
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
9 use crate::utils::files::get_path_from_bytes;
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
10 use crate::utils::hg_path::HgPath;
52760
94e2547e6f3d rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents: 52757
diff changeset
11 use crate::utils::strings::SliceExt;
50975
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
12 use crate::Graph;
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
13 use crate::GraphError;
52396
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
14 use crate::Node;
50974
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
15 use crate::UncheckedRevision;
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
16 use std::path::PathBuf;
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
17
52156
039b7caeb4d9 rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51864
diff changeset
18 use super::options::RevlogOpenOptions;
039b7caeb4d9 rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51864
diff changeset
19
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
20 /// A specialized `Revlog` to work with file data logs.
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
21 pub struct Filelog {
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
22 /// The generic `revlog` format.
52757
5af65969edaf rust-filelog: make Filelog::revlog pub(crate)
Mitchell Kember <mkember@janestreet.com>
parents: 52396
diff changeset
23 pub(crate) revlog: Revlog,
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
24 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
25
50975
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
26 impl Graph for Filelog {
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
27 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
28 self.revlog.parents(rev)
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
29 }
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
30 }
27e773aa607d rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50974
diff changeset
31
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
32 impl Filelog {
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49174
diff changeset
33 pub fn open_vfs(
51864
db7dbe6f7bb2 rust: add Vfs trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51188
diff changeset
34 store_vfs: &crate::vfs::VfsImpl,
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49174
diff changeset
35 file_path: &HgPath,
51188
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
36 options: RevlogOpenOptions,
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49174
diff changeset
37 ) -> Result<Self, HgError> {
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
38 let index_path = store_path(file_path, b".i");
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
39 let data_path = store_path(file_path, b".d");
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49174
diff changeset
40 let revlog =
51188
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
41 Revlog::open(store_vfs, index_path, Some(&data_path), options)?;
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
42 Ok(Self { revlog })
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
43 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
44
51188
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
45 pub fn open(
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
46 repo: &Repo,
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
47 file_path: &HgPath,
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
48 options: RevlogOpenOptions,
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
49 ) -> Result<Self, HgError> {
13f58ce70299 rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50975
diff changeset
50 Self::open_vfs(&repo.store_vfs(), file_path, options)
49517
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49174
diff changeset
51 }
52464a20add0 rhg: parallellize computation of [unsure_is_modified]
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49174
diff changeset
52
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
53 /// The given node ID is that of the file as found in a filelog, not of a
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
54 /// changeset.
47969
87e3f878e65f rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents: 47968
diff changeset
55 pub fn data_for_node(
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
56 &self,
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
57 file_node: impl Into<NodePrefix>,
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48249
diff changeset
58 ) -> Result<FilelogRevisionData, RevlogError> {
47968
6f579618ea7b rust: Rename the `Revlog::get_node_rev` method to `rev_from_node`
Simon Sapin <simon.sapin@octobus.net>
parents: 47963
diff changeset
59 let file_rev = self.revlog.rev_from_node(file_node.into())?;
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
60 self.data_for_unchecked_rev(file_rev.into())
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
61 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
62
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
63 /// The given revision is that of the file as found in a filelog, not of a
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
64 /// changeset.
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
65 pub fn data_for_unchecked_rev(
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
66 &self,
50974
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
67 file_rev: UncheckedRevision,
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48249
diff changeset
68 ) -> Result<FilelogRevisionData, RevlogError> {
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
69 let data: Vec<u8> = self
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
70 .revlog
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
71 .get_data_for_unchecked_rev(file_rev)?
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
72 .into_owned();
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
73 Ok(FilelogRevisionData(data))
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
74 }
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
75
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
76 /// The given node ID is that of the file as found in a filelog, not of a
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
77 /// changeset.
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
78 pub fn entry_for_node(
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
79 &self,
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
80 file_node: impl Into<NodePrefix>,
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
81 ) -> Result<FilelogEntry, RevlogError> {
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
82 let file_rev = self.revlog.rev_from_node(file_node.into())?;
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
83 self.entry(file_rev)
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
84 }
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
85
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
86 /// The given revision is that of the file as found in a filelog, not of a
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
87 /// changeset.
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
88 pub fn entry_for_unchecked_rev(
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
89 &self,
50974
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
90 file_rev: UncheckedRevision,
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
91 ) -> Result<FilelogEntry, RevlogError> {
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
92 Ok(FilelogEntry(
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
93 self.revlog.get_entry_for_unchecked_rev(file_rev)?,
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
94 ))
50974
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
95 }
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
96
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
97 /// Same as [`Self::entry_for_unchecked_rev`] for a checked revision.
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
98 pub fn entry(
50974
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
99 &self,
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
100 file_rev: Revision,
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
101 ) -> Result<FilelogEntry, RevlogError> {
52290
a3fa37bdb7ec rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52156
diff changeset
102 Ok(FilelogEntry(self.revlog.get_entry(file_rev)?))
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
103 }
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
104 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
105
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
106 fn store_path(hg_path: &HgPath, suffix: &[u8]) -> PathBuf {
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
107 let encoded_bytes =
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
108 path_encode(&[b"data/", hg_path.as_bytes(), suffix].concat());
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
109 get_path_from_bytes(&encoded_bytes).into()
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
110 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
111
52757
5af65969edaf rust-filelog: make Filelog::revlog pub(crate)
Mitchell Kember <mkember@janestreet.com>
parents: 52396
diff changeset
112 pub struct FilelogEntry<'a>(pub(crate) RevlogEntry<'a>);
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
113
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
114 impl FilelogEntry<'_> {
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
115 /// `self.data()` can be expensive, with decompression and delta
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
116 /// resolution.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
117 ///
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
118 /// *Without* paying this cost, based on revlog index information
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
119 /// including `RevlogEntry::uncompressed_len`:
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
120 ///
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
121 /// * Returns `true` if the length that `self.data().file_data().len()`
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
122 /// would return is definitely **not equal** to `other_len`.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
123 /// * Returns `false` if available information is inconclusive.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
124 pub fn file_data_len_not_equal_to(&self, other_len: u64) -> bool {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
125 // Relevant code that implement this behavior in Python code:
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
126 // basefilectx.cmp, filelog.size, storageutil.filerevisioncopied,
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
127 // revlog.size, revlog.rawsize
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
128
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
129 // Let’s call `file_data_len` what would be returned by
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
130 // `self.data().file_data().len()`.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
131
49174
3f86ee422095 censor: make rhg fall back to python when encountering a censored node
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49089
diff changeset
132 if self.0.is_censored() {
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
133 let file_data_len = 0;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
134 return other_len != file_data_len;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
135 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
136
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
137 if self.0.has_length_affecting_flag_processor() {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
138 // We can’t conclude anything about `file_data_len`.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
139 return false;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
140 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
141
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
142 // Revlog revisions (usually) have metadata for the size of
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
143 // their data after decompression and delta resolution
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
144 // as would be returned by `Revlog::get_rev_data`.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
145 //
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
146 // For filelogs this is the file’s contents preceded by an optional
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
147 // metadata block.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
148 let uncompressed_len = if let Some(l) = self.0.uncompressed_len() {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
149 l as u64
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
150 } else {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
151 // The field was set to -1, the actual uncompressed len is unknown.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
152 // We need to decompress to say more.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
153 return false;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
154 };
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
155 // `uncompressed_len = file_data_len + optional_metadata_len`,
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
156 // so `file_data_len <= uncompressed_len`.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
157 if uncompressed_len < other_len {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
158 // Transitively, `file_data_len < other_len`.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
159 // So `other_len != file_data_len` definitely.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
160 return true;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
161 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
162
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
163 if uncompressed_len == other_len + 4 {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
164 // It’s possible that `file_data_len == other_len` with an empty
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
165 // metadata block (2 start marker bytes + 2 end marker bytes).
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
166 // This happens when there wouldn’t otherwise be metadata, but
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
167 // the first 2 bytes of file data happen to match a start marker
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
168 // and would be ambiguous.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
169 return false;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
170 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
171
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
172 if !self.0.has_p1() {
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
173 // There may or may not be copy metadata, so we can’t deduce more
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
174 // about `file_data_len` without computing file data.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
175 return false;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
176 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
177
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
178 // Filelog ancestry is not meaningful in the way changelog ancestry is.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
179 // It only provides hints to delta generation.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
180 // p1 and p2 are set to null when making a copy or rename since
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
181 // contents are likely unrelatedto what might have previously existed
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
182 // at the destination path.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
183 //
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
184 // Conversely, since here p1 is non-null, there is no copy metadata.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
185 // Note that this reasoning may be invalidated in the presence of
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
186 // merges made by some previous versions of Mercurial that
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
187 // swapped p1 and p2. See <https://bz.mercurial-scm.org/show_bug.cgi?id=6528>
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
188 // and `tests/test-issue6528.t`.
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
189 //
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
190 // Since copy metadata is currently the only kind of metadata
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
191 // kept in revlog data of filelogs,
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
192 // this `FilelogEntry` does not have such metadata:
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
193 let file_data_len = uncompressed_len;
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
194
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49517
diff changeset
195 file_data_len != other_len
48546
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
196 }
e91aa800ae5b rhg: desambiguate status without decompressing filelog if possible
Simon Sapin <simon.sapin@octobus.net>
parents: 48542
diff changeset
197
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
198 pub fn data(&self) -> Result<FilelogRevisionData, HgError> {
50974
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
199 let data = self.0.data();
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
200 match data {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
201 Ok(data) => Ok(FilelogRevisionData(data.into_owned())),
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
202 // Errors other than `HgError` should not happen at this point
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
203 Err(e) => match e {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
204 RevlogError::Other(hg_error) => Err(hg_error),
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
205 revlog_error => Err(HgError::abort(
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
206 revlog_error.to_string(),
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
207 exit_codes::ABORT,
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
208 None,
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
209 )),
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
210 },
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49937
diff changeset
211 }
48542
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
212 }
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
213 }
35c47015b9b7 rhg: Expose FilelogEntry that wraps RevlogEntry
Simon Sapin <simon.sapin@octobus.net>
parents: 48541
diff changeset
214
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48249
diff changeset
215 /// The data for one revision in a filelog, uncompressed and delta-resolved.
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48249
diff changeset
216 pub struct FilelogRevisionData(Vec<u8>);
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
217
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48249
diff changeset
218 impl FilelogRevisionData {
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
219 /// Split into metadata and data
52396
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
220 pub fn split(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
221 &self,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
222 ) -> Result<(FilelogRevisionMetadata<'_>, &[u8]), HgError> {
52291
f90796d33aa0 rust: fix clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52290
diff changeset
223 const DELIMITER: &[u8; 2] = b"\x01\n";
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
224
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
225 if let Some(rest) = self.0.drop_prefix(DELIMITER) {
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
226 if let Some((metadata, data)) = rest.split_2_by_slice(DELIMITER) {
52396
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
227 Ok((FilelogRevisionMetadata(Some(metadata)), data))
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
228 } else {
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
229 Err(HgError::corrupted(
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
230 "Missing metadata end delimiter in filelog entry",
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
231 ))
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
232 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
233 } else {
52396
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
234 Ok((FilelogRevisionMetadata(None), &self.0))
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
235 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
236 }
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
237
52396
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
238 /// Returns the metadata header.
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
239 pub fn metadata(&self) -> Result<FilelogRevisionMetadata<'_>, HgError> {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
240 let (metadata, _data) = self.split()?;
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
241 Ok(metadata)
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
242 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
243
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
244 /// Returns the file contents at this revision, stripped of any metadata
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48249
diff changeset
245 pub fn file_data(&self) -> Result<&[u8], HgError> {
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
246 let (_metadata, data) = self.split()?;
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
247 Ok(data)
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
248 }
48237
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
249
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
250 /// Consume the entry, and convert it into data, discarding any metadata,
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
251 /// if present.
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48249
diff changeset
252 pub fn into_file_data(self) -> Result<Vec<u8>, HgError> {
52396
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
253 if let (FilelogRevisionMetadata(Some(_)), data) = self.split()? {
48237
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
254 Ok(data.to_owned())
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
255 } else {
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
256 Ok(self.0)
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
257 }
027ebad952ac rhg: internally, return a structured representation from hg cat
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 47969
diff changeset
258 }
47961
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
259 }
52396
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
260
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
261 /// The optional metadata header included in [`FilelogRevisionData`].
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
262 pub struct FilelogRevisionMetadata<'a>(Option<&'a [u8]>);
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
263
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
264 /// Fields parsed from [`FilelogRevisionMetadata`].
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
265 #[derive(Debug, PartialEq, Default)]
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
266 pub struct FilelogRevisionMetadataFields<'a> {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
267 /// True if the file revision data is censored.
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
268 pub censored: bool,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
269 /// Path of the copy source.
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
270 pub copy: Option<&'a HgPath>,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
271 /// Filelog node ID of the copy source.
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
272 pub copyrev: Option<Node>,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
273 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
274
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
275 impl<'a> FilelogRevisionMetadata<'a> {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
276 /// Parses the metadata fields.
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
277 pub fn parse(self) -> Result<FilelogRevisionMetadataFields<'a>, HgError> {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
278 let mut fields = FilelogRevisionMetadataFields::default();
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
279 if let Some(metadata) = self.0 {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
280 let mut rest = metadata;
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
281 while !rest.is_empty() {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
282 let Some(colon_idx) = memchr::memchr(b':', rest) else {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
283 return Err(HgError::corrupted(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
284 "File metadata header line missing colon",
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
285 ));
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
286 };
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
287 if rest.get(colon_idx + 1) != Some(&b' ') {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
288 return Err(HgError::corrupted(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
289 "File metadata header line missing space",
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
290 ));
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
291 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
292 let key = &rest[..colon_idx];
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
293 rest = &rest[colon_idx + 2..];
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
294 let Some(newline_idx) = memchr::memchr(b'\n', rest) else {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
295 return Err(HgError::corrupted(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
296 "File metadata header line missing newline",
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
297 ));
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
298 };
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
299 let value = &rest[..newline_idx];
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
300 match key {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
301 b"censored" => {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
302 match value {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
303 b"" => fields.censored = true,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
304 _ => return Err(HgError::corrupted(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
305 "File metadata header 'censored' field has nonempty value",
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
306 )),
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
307 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
308 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
309 b"copy" => fields.copy = Some(HgPath::new(value)),
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
310 b"copyrev" => {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
311 fields.copyrev = Some(Node::from_hex_for_repo(value)?)
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
312 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
313 _ => {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
314 return Err(HgError::corrupted(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
315 format!(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
316 "File metadata header has unrecognized key '{}'",
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
317 String::from_utf8_lossy(key),
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
318 ),
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
319 ))
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
320 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
321 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
322 rest = &rest[newline_idx + 1..];
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
323 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
324 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
325 Ok(fields)
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
326 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
327 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
328
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
329 #[cfg(test)]
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
330 mod tests {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
331 use super::*;
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
332 use format_bytes::format_bytes;
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
333
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
334 #[test]
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
335 fn test_parse_no_metadata() {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
336 let data = FilelogRevisionData(b"data".to_vec());
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
337 let fields = data.metadata().unwrap().parse().unwrap();
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
338 assert_eq!(fields, Default::default());
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
339 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
340
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
341 #[test]
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
342 fn test_parse_empty_metadata() {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
343 let data = FilelogRevisionData(b"\x01\n\x01\ndata".to_vec());
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
344 let fields = data.metadata().unwrap().parse().unwrap();
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
345 assert_eq!(fields, Default::default());
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
346 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
347
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
348 #[test]
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
349 fn test_parse_one_field() {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
350 let data =
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
351 FilelogRevisionData(b"\x01\ncopy: foo\n\x01\ndata".to_vec());
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
352 let fields = data.metadata().unwrap().parse().unwrap();
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
353 assert_eq!(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
354 fields,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
355 FilelogRevisionMetadataFields {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
356 copy: Some(HgPath::new("foo")),
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
357 ..Default::default()
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
358 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
359 );
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
360 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
361
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
362 #[test]
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
363 fn test_parse_all_fields() {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
364 let sha = b"215d5d1546f82a79481eb2df513a7bc341bdf17f";
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
365 let data = FilelogRevisionData(format_bytes!(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
366 b"\x01\ncensored: \ncopy: foo\ncopyrev: {}\n\x01\ndata",
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
367 sha
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
368 ));
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
369 let fields = data.metadata().unwrap().parse().unwrap();
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
370 assert_eq!(
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
371 fields,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
372 FilelogRevisionMetadataFields {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
373 censored: true,
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
374 copy: Some(HgPath::new("foo")),
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
375 copyrev: Some(Node::from_hex(sha).unwrap()),
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
376 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
377 );
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
378 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
379
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
380 #[test]
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
381 fn test_parse_invalid_metadata() {
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
382 let data =
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
383 FilelogRevisionData(b"\x01\nbad: value\n\x01\ndata".to_vec());
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
384 let err = data.metadata().unwrap().parse().unwrap_err();
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
385 assert!(err.to_string().contains("unrecognized key 'bad'"));
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
386 }
b0b6c28b340b hg-core: add filelog metadata header parsing
Mitchell Kember <mkember@janestreet.com>
parents: 52291
diff changeset
387 }