annotate rust/hg-core/src/revlog/changelog.rs @ 50978:27e773aa607d

rust: implement the `Graph` trait for all revlogs This is trivial and makes all the algorithms relying on the trait usable for more use cases.
author Raphaël Gomès <rgomes@octobus.net>
date Thu, 10 Aug 2023 11:01:07 +0200
parents 1928b770e3e7
children 13f58ce70299 d626e5e7bbbe
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46433
diff changeset
1 use crate::errors::HgError;
50747
9865af7191d2 rust-changelog: removed now useless early conditional for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents: 50746
diff changeset
2 use crate::revlog::Revision;
46744
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
3 use crate::revlog::{Node, NodePrefix};
49937
750409505286 rust-clippy: merge "revlog" module definition and struct implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
4 use crate::revlog::{Revlog, RevlogEntry, RevlogError};
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
5 use crate::utils::hg_path::HgPath;
49090
a5ef50becea8 rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49089
diff changeset
6 use crate::vfs::Vfs;
50978
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
7 use crate::{Graph, GraphError, UncheckedRevision};
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
8 use itertools::Itertools;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
9 use std::ascii::escape_default;
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
10 use std::borrow::Cow;
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
11 use std::fmt::{Debug, Formatter};
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
12
50409
b47a9316050a rust-changelog: made doc-comments more consistent
Georges Racinet <georges.racinet@octobus.net>
parents: 49937
diff changeset
13 /// A specialized `Revlog` to work with changelog data format.
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
14 pub struct Changelog {
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
15 /// The generic `revlog` format.
46433
4b381dbbf8b7 rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
16 pub(crate) revlog: Revlog,
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
17 }
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
18
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
19 impl Changelog {
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
20 /// Open the `changelog` of a repository given by its root.
49090
a5ef50becea8 rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49089
diff changeset
21 pub fn open(store_vfs: &Vfs, use_nodemap: bool) -> Result<Self, HgError> {
a5ef50becea8 rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49089
diff changeset
22 let revlog =
a5ef50becea8 rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49089
diff changeset
23 Revlog::open(store_vfs, "00changelog.i", None, use_nodemap)?;
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
24 Ok(Self { revlog })
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
25 }
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
26
50409
b47a9316050a rust-changelog: made doc-comments more consistent
Georges Racinet <georges.racinet@octobus.net>
parents: 49937
diff changeset
27 /// Return the `ChangelogRevisionData` for the given node ID.
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
28 pub fn data_for_node(
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
29 &self,
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46167
diff changeset
30 node: NodePrefix,
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48198
diff changeset
31 ) -> Result<ChangelogRevisionData, RevlogError> {
47968
6f579618ea7b rust: Rename the `Revlog::get_node_rev` method to `rev_from_node`
Simon Sapin <simon.sapin@octobus.net>
parents: 47967
diff changeset
32 let rev = self.revlog.rev_from_node(node)?;
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
33 self.entry_for_checked_rev(rev)?.data()
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
34 }
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
35
50411
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
36 /// Return the [`ChangelogEntry`] for the given revision number.
49065
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
37 pub fn entry_for_rev(
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
38 &self,
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
39 rev: UncheckedRevision,
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
40 ) -> Result<ChangelogEntry, RevlogError> {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
41 let revlog_entry = self.revlog.get_entry(rev)?;
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
42 Ok(ChangelogEntry { revlog_entry })
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
43 }
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
44
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
45 /// Same as [`Self::entry_for_rev`] for checked revisions.
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
46 fn entry_for_checked_rev(
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
47 &self,
49065
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
48 rev: Revision,
50411
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
49 ) -> Result<ChangelogEntry, RevlogError> {
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
50 let revlog_entry = self.revlog.get_entry_for_checked_rev(rev)?;
50411
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
51 Ok(ChangelogEntry { revlog_entry })
49065
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
52 }
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
53
50409
b47a9316050a rust-changelog: made doc-comments more consistent
Georges Racinet <georges.racinet@octobus.net>
parents: 49937
diff changeset
54 /// Return the [`ChangelogRevisionData`] for the given revision number.
50411
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
55 ///
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
56 /// This is a useful shortcut in case the caller does not need the
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
57 /// generic revlog information (parents, hashes etc). Otherwise
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
58 /// consider taking a [`ChangelogEntry`] with
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
59 /// [entry_for_rev](`Self::entry_for_rev`) and doing everything from there.
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
60 pub fn data_for_rev(
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
61 &self,
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
62 rev: UncheckedRevision,
48540
20d0d896183e rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents: 48198
diff changeset
63 ) -> Result<ChangelogRevisionData, RevlogError> {
50411
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
64 self.entry_for_rev(rev)?.data()
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
65 }
46744
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
66
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
67 pub fn node_from_rev(&self, rev: UncheckedRevision) -> Option<&Node> {
47967
6c653d9d41b8 rust: Make private the `index` field of the `Revlog` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47964
diff changeset
68 self.revlog.node_from_rev(rev)
46744
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
69 }
49065
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
70
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
71 pub fn rev_from_node(
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
72 &self,
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
73 node: NodePrefix,
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
74 ) -> Result<Revision, RevlogError> {
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
75 self.revlog.rev_from_node(node)
5d205e476057 rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents: 49064
diff changeset
76 }
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
77 }
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
78
50978
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
79 impl Graph for Changelog {
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
80 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: 50977
diff changeset
81 self.revlog.parents(rev)
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
82 }
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
83 }
27e773aa607d rust: implement the `Graph` trait for all revlogs
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
84
50411
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
85 /// A specialized `RevlogEntry` for `changelog` data format
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
86 ///
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
87 /// This is a `RevlogEntry` with the added semantics that the associated
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
88 /// data should meet the requirements for `changelog`, materialized by
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
89 /// the fact that `data()` constructs a `ChangelogRevisionData`.
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
90 /// In case that promise would be broken, the `data` method returns an error.
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
91 #[derive(Clone)]
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
92 pub struct ChangelogEntry<'changelog> {
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
93 /// Same data, as a generic `RevlogEntry`.
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
94 pub(crate) revlog_entry: RevlogEntry<'changelog>,
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
95 }
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
96
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
97 impl<'changelog> ChangelogEntry<'changelog> {
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
98 pub fn data<'a>(
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
99 &'a self,
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
100 ) -> Result<ChangelogRevisionData<'changelog>, RevlogError> {
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
101 let bytes = self.revlog_entry.data()?;
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
102 if bytes.is_empty() {
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
103 Ok(ChangelogRevisionData::null())
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
104 } else {
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
105 Ok(ChangelogRevisionData::new(bytes).map_err(|err| {
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
106 RevlogError::Other(HgError::CorruptedRepository(format!(
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
107 "Invalid changelog data for revision {}: {:?}",
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
108 self.revlog_entry.revision(),
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
109 err
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
110 )))
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
111 })?)
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
112 }
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
113 }
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
114
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
115 /// Obtain a reference to the underlying `RevlogEntry`.
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
116 ///
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
117 /// This allows the caller to access the information that is common
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
118 /// to all revlog entries: revision number, node id, parent revisions etc.
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
119 pub fn as_revlog_entry(&self) -> &RevlogEntry {
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
120 &self.revlog_entry
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
121 }
50414
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
122
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
123 pub fn p1_entry(&self) -> Result<Option<ChangelogEntry>, RevlogError> {
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
124 Ok(self
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
125 .revlog_entry
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
126 .p1_entry()?
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
127 .map(|revlog_entry| Self { revlog_entry }))
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
128 }
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
129
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
130 pub fn p2_entry(&self) -> Result<Option<ChangelogEntry>, RevlogError> {
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
131 Ok(self
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
132 .revlog_entry
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
133 .p2_entry()?
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
134 .map(|revlog_entry| Self { revlog_entry }))
071a6c1d291e rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents: 50411
diff changeset
135 }
50411
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
136 }
841b13e6e84c rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents: 50410
diff changeset
137
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
138 /// `Changelog` entry which knows how to interpret the `changelog` data bytes.
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
139 #[derive(PartialEq)]
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
140 pub struct ChangelogRevisionData<'changelog> {
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
141 /// The data bytes of the `changelog` entry.
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
142 bytes: Cow<'changelog, [u8]>,
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
143 /// The end offset for the hex manifest (not including the newline)
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
144 manifest_end: usize,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
145 /// The end offset for the user+email (not including the newline)
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
146 user_end: usize,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
147 /// The end offset for the timestamp+timezone+extras (not including the
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
148 /// newline)
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
149 timestamp_end: usize,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
150 /// The end offset for the file list (not including the newline)
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
151 files_end: usize,
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
152 }
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
153
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
154 impl<'changelog> ChangelogRevisionData<'changelog> {
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
155 fn new(bytes: Cow<'changelog, [u8]>) -> Result<Self, HgError> {
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
156 let mut line_iter = bytes.split(|b| b == &b'\n');
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
157 let manifest_end = line_iter
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
158 .next()
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
159 .expect("Empty iterator from split()?")
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
160 .len();
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
161 let user_slice = line_iter.next().ok_or_else(|| {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
162 HgError::corrupted("Changeset data truncated after manifest line")
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
163 })?;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
164 let user_end = manifest_end + 1 + user_slice.len();
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
165 let timestamp_slice = line_iter.next().ok_or_else(|| {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
166 HgError::corrupted("Changeset data truncated after user line")
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
167 })?;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
168 let timestamp_end = user_end + 1 + timestamp_slice.len();
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
169 let mut files_end = timestamp_end + 1;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
170 loop {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
171 let line = line_iter.next().ok_or_else(|| {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
172 HgError::corrupted("Changeset data truncated in files list")
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
173 })?;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
174 if line.is_empty() {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
175 if files_end == bytes.len() {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
176 // The list of files ended with a single newline (there
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
177 // should be two)
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
178 return Err(HgError::corrupted(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
179 "Changeset data truncated after files list",
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
180 ));
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
181 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
182 files_end -= 1;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
183 break;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
184 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
185 files_end += line.len() + 1;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
186 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
187
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
188 Ok(Self {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
189 bytes,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
190 manifest_end,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
191 user_end,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
192 timestamp_end,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
193 files_end,
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
194 })
49063
cc132255261b rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 49062
diff changeset
195 }
cc132255261b rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 49062
diff changeset
196
cc132255261b rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 49062
diff changeset
197 fn null() -> Self {
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
198 Self::new(Cow::Borrowed(
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
199 b"0000000000000000000000000000000000000000\n\n0 0\n\n",
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
200 ))
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
201 .unwrap()
49063
cc132255261b rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 49062
diff changeset
202 }
cc132255261b rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 49062
diff changeset
203
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
204 /// Return an iterator over the lines of the entry.
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
205 pub fn lines(&self) -> impl Iterator<Item = &[u8]> {
49062
fb82b5cb8301 rust-changelog: don't skip empty lines when iterating over changeset lines
Martin von Zweigbergk <martinvonz@google.com>
parents: 48541
diff changeset
206 self.bytes.split(|b| b == &b'\n')
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
207 }
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
208
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
209 /// Return the node id of the `manifest` referenced by this `changelog`
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
210 /// entry.
47964
796206e74b10 rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents: 47963
diff changeset
211 pub fn manifest_node(&self) -> Result<Node, HgError> {
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
212 let manifest_node_hex = &self.bytes[..self.manifest_end];
49063
cc132255261b rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents: 49062
diff changeset
213 Node::from_hex_for_repo(manifest_node_hex)
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
214 }
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
215
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
216 /// The full user string (usually a name followed by an email enclosed in
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
217 /// angle brackets)
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
218 pub fn user(&self) -> &[u8] {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
219 &self.bytes[self.manifest_end + 1..self.user_end]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
220 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
221
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
222 /// The full timestamp line (timestamp in seconds, offset in seconds, and
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
223 /// possibly extras)
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
224 // TODO: We should expose this in a more useful way
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
225 pub fn timestamp_line(&self) -> &[u8] {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
226 &self.bytes[self.user_end + 1..self.timestamp_end]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
227 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
228
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
229 /// The files changed in this revision.
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
230 pub fn files(&self) -> impl Iterator<Item = &HgPath> {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
231 self.bytes[self.timestamp_end + 1..self.files_end]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
232 .split(|b| b == &b'\n')
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49096
diff changeset
233 .map(HgPath::new)
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
234 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
235
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
236 /// The change description.
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
237 pub fn description(&self) -> &[u8] {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
238 &self.bytes[self.files_end + 2..]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
239 }
45532
c2317b7624fd hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
240 }
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
241
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
242 impl Debug for ChangelogRevisionData<'_> {
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
243 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
244 f.debug_struct("ChangelogRevisionData")
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
245 .field("bytes", &debug_bytes(&self.bytes))
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
246 .field("manifest", &debug_bytes(&self.bytes[..self.manifest_end]))
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
247 .field(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
248 "user",
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
249 &debug_bytes(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
250 &self.bytes[self.manifest_end + 1..self.user_end],
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
251 ),
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
252 )
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
253 .field(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
254 "timestamp",
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
255 &debug_bytes(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
256 &self.bytes[self.user_end + 1..self.timestamp_end],
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
257 ),
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
258 )
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
259 .field(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
260 "files",
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
261 &debug_bytes(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
262 &self.bytes[self.timestamp_end + 1..self.files_end],
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
263 ),
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
264 )
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
265 .field(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
266 "description",
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
267 &debug_bytes(&self.bytes[self.files_end + 2..]),
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
268 )
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
269 .finish()
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
270 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
271 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
272
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
273 fn debug_bytes(bytes: &[u8]) -> String {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
274 String::from_utf8_lossy(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
275 &bytes.iter().flat_map(|b| escape_default(*b)).collect_vec(),
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
276 )
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
277 .to_string()
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
278 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
279
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
280 #[cfg(test)]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
281 mod tests {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
282 use super::*;
50410
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
283 use crate::vfs::Vfs;
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
284 use crate::NULL_REVISION;
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
285 use pretty_assertions::assert_eq;
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
286
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
287 #[test]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
288 fn test_create_changelogrevisiondata_invalid() {
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
289 // Completely empty
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
290 assert!(ChangelogRevisionData::new(Cow::Borrowed(b"abcd")).is_err());
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
291 // No newline after manifest
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
292 assert!(ChangelogRevisionData::new(Cow::Borrowed(b"abcd")).is_err());
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
293 // No newline after user
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
294 assert!(ChangelogRevisionData::new(Cow::Borrowed(b"abcd\n")).is_err());
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
295 // No newline after timestamp
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
296 assert!(
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
297 ChangelogRevisionData::new(Cow::Borrowed(b"abcd\n\n0 0")).is_err()
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
298 );
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
299 // Missing newline after files
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
300 assert!(ChangelogRevisionData::new(Cow::Borrowed(
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
301 b"abcd\n\n0 0\nfile1\nfile2"
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
302 ))
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
303 .is_err(),);
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
304 // Only one newline after files
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
305 assert!(ChangelogRevisionData::new(Cow::Borrowed(
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
306 b"abcd\n\n0 0\nfile1\nfile2\n"
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
307 ))
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
308 .is_err(),);
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
309 }
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
310
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
311 #[test]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
312 fn test_create_changelogrevisiondata() {
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
313 let data = ChangelogRevisionData::new(Cow::Borrowed(
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
314 b"0123456789abcdef0123456789abcdef01234567
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
315 Some One <someone@example.com>
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
316 0 0
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
317 file1
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
318 file2
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
319
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
320 some
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
321 commit
49096
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
322 message",
07ec9f4f24bf changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents: 49090
diff changeset
323 ))
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
324 .unwrap();
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
325 assert_eq!(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
326 data.manifest_node().unwrap(),
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
327 Node::from_hex("0123456789abcdef0123456789abcdef01234567")
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
328 .unwrap()
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
329 );
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
330 assert_eq!(data.user(), b"Some One <someone@example.com>");
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
331 assert_eq!(data.timestamp_line(), b"0 0");
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
332 assert_eq!(
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
333 data.files().collect_vec(),
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
334 vec![HgPath::new("file1"), HgPath::new("file2")]
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
335 );
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
336 assert_eq!(data.description(), b"some\ncommit\nmessage");
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
337 }
50410
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
338
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
339 #[test]
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
340 fn test_data_from_rev_null() -> Result<(), RevlogError> {
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
341 // an empty revlog will be enough for this case
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
342 let temp = tempfile::tempdir().unwrap();
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
343 let vfs = Vfs { base: temp.path() };
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
344 std::fs::write(temp.path().join("foo.i"), b"").unwrap();
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
345 let revlog = Revlog::open(&vfs, "foo.i", None, false).unwrap();
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
346
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
347 let changelog = Changelog { revlog };
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
348 assert_eq!(
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
349 changelog.data_for_rev(NULL_REVISION.into())?,
50410
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
350 ChangelogRevisionData::null()
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
351 );
50746
124c44b5cfad rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents: 50414
diff changeset
352 // same with the intermediate entry object
124c44b5cfad rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents: 50414
diff changeset
353 assert_eq!(
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 50747
diff changeset
354 changelog.entry_for_rev(NULL_REVISION.into())?.data()?,
50746
124c44b5cfad rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents: 50414
diff changeset
355 ChangelogRevisionData::null()
124c44b5cfad rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents: 50414
diff changeset
356 );
50410
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
357 Ok(())
b5dd6d6d6fa6 rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents: 50409
diff changeset
358 }
49064
95da3e99cbd8 rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents: 49063
diff changeset
359 }