Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/revlog/changelog.rs @ 51864:db7dbe6f7bb2
rust: add Vfs trait
This will allow for the use of multiple vfs like in the Python implementation,
as well as hiding the details of the upcoming Python vfs wrapper to hg-core.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 19 Jun 2024 14:49:35 +0200 |
parents | 69b804c8e09e |
children | 1d6982827c4b |
rev | line source |
---|---|
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
1 use std::ascii::escape_default; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
2 use std::borrow::Cow; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
3 use std::collections::BTreeMap; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
4 use std::fmt::{Debug, Formatter}; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
5 use std::{iter, str}; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
6 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
7 use chrono::{DateTime, FixedOffset, NaiveDateTime}; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
8 use itertools::{Either, Itertools}; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
9 |
46443
43d63979a75e
rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents:
46433
diff
changeset
|
10 use crate::errors::HgError; |
51721
bbe59cc5d2e1
rust-changelog: accessing the index
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
51703
diff
changeset
|
11 use crate::revlog::Index; |
50744
9865af7191d2
rust-changelog: removed now useless early conditional for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents:
50743
diff
changeset
|
12 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
|
13 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
|
14 use crate::revlog::{Revlog, RevlogEntry, RevlogError}; |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
15 use crate::utils::hg_path::HgPath; |
51864 | 16 use crate::vfs::VfsImpl; |
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
|
17 use crate::{Graph, GraphError, RevlogOpenOptions, UncheckedRevision}; |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
18 |
50406
b47a9316050a
rust-changelog: made doc-comments more consistent
Georges Racinet <georges.racinet@octobus.net>
parents:
49937
diff
changeset
|
19 /// 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
|
20 pub struct Changelog { |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
21 /// The generic `revlog` format. |
46433
4b381dbbf8b7
rhg: centralize parsing of `--rev` CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46431
diff
changeset
|
22 pub(crate) revlog: Revlog, |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
23 } |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
24 |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
25 impl Changelog { |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
26 /// Open the `changelog` of a repository given by its root. |
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
|
27 pub fn open( |
51864 | 28 store_vfs: &VfsImpl, |
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
|
29 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
|
30 ) -> 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
|
31 let revlog = Revlog::open(store_vfs, "00changelog.i", None, options)?; |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
32 Ok(Self { revlog }) |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
33 } |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
34 |
50406
b47a9316050a
rust-changelog: made doc-comments more consistent
Georges Racinet <georges.racinet@octobus.net>
parents:
49937
diff
changeset
|
35 /// 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
|
36 pub fn data_for_node( |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
37 &self, |
46431
645ee7225fab
rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents:
46167
diff
changeset
|
38 node: NodePrefix, |
48540
20d0d896183e
rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents:
48198
diff
changeset
|
39 ) -> 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
|
40 let rev = self.revlog.rev_from_node(node)?; |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
41 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
|
42 } |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
43 |
50408
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
44 /// 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
|
45 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
|
46 &self, |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
47 rev: UncheckedRevision, |
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
48 ) -> Result<ChangelogEntry, RevlogError> { |
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
49 let revlog_entry = self.revlog.get_entry(rev)?; |
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
50 Ok(ChangelogEntry { revlog_entry }) |
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
51 } |
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
52 |
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
53 /// 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:
50744
diff
changeset
|
54 fn entry_for_checked_rev( |
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
55 &self, |
49065
5d205e476057
rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents:
49064
diff
changeset
|
56 rev: Revision, |
50408
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
57 ) -> Result<ChangelogEntry, RevlogError> { |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
58 let revlog_entry = self.revlog.get_entry_for_checked_rev(rev)?; |
50408
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
59 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
|
60 } |
5d205e476057
rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents:
49064
diff
changeset
|
61 |
50406
b47a9316050a
rust-changelog: made doc-comments more consistent
Georges Racinet <georges.racinet@octobus.net>
parents:
49937
diff
changeset
|
62 /// Return the [`ChangelogRevisionData`] for the given revision number. |
50408
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
63 /// |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
64 /// 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:
50407
diff
changeset
|
65 /// generic revlog information (parents, hashes etc). Otherwise |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
66 /// consider taking a [`ChangelogEntry`] with |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
67 /// [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
|
68 pub fn data_for_rev( |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
69 &self, |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
70 rev: UncheckedRevision, |
48540
20d0d896183e
rhg: Rename some revlog-related types and methods
Simon Sapin <simon.sapin@octobus.net>
parents:
48198
diff
changeset
|
71 ) -> Result<ChangelogRevisionData, RevlogError> { |
50408
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
72 self.entry_for_rev(rev)?.data() |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
73 } |
46744
b1f2c2b336ec
rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
74 |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
75 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
|
76 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
|
77 } |
49065
5d205e476057
rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents:
49064
diff
changeset
|
78 |
5d205e476057
rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents:
49064
diff
changeset
|
79 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
|
80 &self, |
5d205e476057
rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents:
49064
diff
changeset
|
81 node: NodePrefix, |
5d205e476057
rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents:
49064
diff
changeset
|
82 ) -> Result<Revision, RevlogError> { |
5d205e476057
rust-revlog: add methods for getting parent revs and entries
Martin von Zweigbergk <martinvonz@google.com>
parents:
49064
diff
changeset
|
83 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
|
84 } |
51721
bbe59cc5d2e1
rust-changelog: accessing the index
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
51703
diff
changeset
|
85 |
bbe59cc5d2e1
rust-changelog: accessing the index
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
51703
diff
changeset
|
86 pub fn get_index(&self) -> &Index { |
bbe59cc5d2e1
rust-changelog: accessing the index
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
51703
diff
changeset
|
87 &self.revlog.index |
bbe59cc5d2e1
rust-changelog: accessing the index
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
51703
diff
changeset
|
88 } |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
89 } |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
90 |
50975
27e773aa607d
rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50974
diff
changeset
|
91 impl Graph for Changelog { |
27e773aa607d
rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50974
diff
changeset
|
92 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
|
93 self.revlog.parents(rev) |
27e773aa607d
rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50974
diff
changeset
|
94 } |
27e773aa607d
rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50974
diff
changeset
|
95 } |
27e773aa607d
rust: implement the `Graph` trait for all revlogs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50974
diff
changeset
|
96 |
50408
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
97 /// A specialized `RevlogEntry` for `changelog` data format |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
98 /// |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
99 /// 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:
50407
diff
changeset
|
100 /// data should meet the requirements for `changelog`, materialized by |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
101 /// the fact that `data()` constructs a `ChangelogRevisionData`. |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
102 /// 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:
50407
diff
changeset
|
103 #[derive(Clone)] |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
104 pub struct ChangelogEntry<'changelog> { |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
105 /// Same data, as a generic `RevlogEntry`. |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
106 pub(crate) revlog_entry: RevlogEntry<'changelog>, |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
107 } |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
108 |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
109 impl<'changelog> ChangelogEntry<'changelog> { |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
110 pub fn data<'a>( |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
111 &'a self, |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
112 ) -> Result<ChangelogRevisionData<'changelog>, RevlogError> { |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
113 let bytes = self.revlog_entry.data()?; |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
114 if bytes.is_empty() { |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
115 Ok(ChangelogRevisionData::null()) |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
116 } else { |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
117 Ok(ChangelogRevisionData::new(bytes).map_err(|err| { |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
118 RevlogError::Other(HgError::CorruptedRepository(format!( |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
119 "Invalid changelog data for revision {}: {:?}", |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
120 self.revlog_entry.revision(), |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
121 err |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
122 ))) |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
123 })?) |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
124 } |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
125 } |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
126 |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
127 /// Obtain a reference to the underlying `RevlogEntry`. |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
128 /// |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
129 /// 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:
50407
diff
changeset
|
130 /// 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:
50407
diff
changeset
|
131 pub fn as_revlog_entry(&self) -> &RevlogEntry { |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
132 &self.revlog_entry |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
133 } |
50411
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
134 |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
135 pub fn p1_entry(&self) -> Result<Option<ChangelogEntry>, RevlogError> { |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
136 Ok(self |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
137 .revlog_entry |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
138 .p1_entry()? |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
139 .map(|revlog_entry| Self { revlog_entry })) |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
140 } |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
141 |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
142 pub fn p2_entry(&self) -> Result<Option<ChangelogEntry>, RevlogError> { |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
143 Ok(self |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
144 .revlog_entry |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
145 .p2_entry()? |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
146 .map(|revlog_entry| Self { revlog_entry })) |
071a6c1d291e
rust-changelog: introduce ChangelogEntry parent entries accessors
Georges Racinet <georges.racinet@octobus.net>
parents:
50408
diff
changeset
|
147 } |
50408
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
148 } |
841b13e6e84c
rust-changelog: introducing an intermediate `ChangelogEntry`
Georges Racinet <georges.racinet@octobus.net>
parents:
50407
diff
changeset
|
149 |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
150 /// `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
|
151 #[derive(PartialEq)] |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
152 pub struct ChangelogRevisionData<'changelog> { |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
153 /// 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
|
154 bytes: Cow<'changelog, [u8]>, |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
155 /// 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
|
156 manifest_end: usize, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
157 /// 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
|
158 user_end: usize, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
159 /// 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
|
160 /// newline) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
161 timestamp_end: usize, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
162 /// 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
|
163 files_end: usize, |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
164 } |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
165 |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
166 impl<'changelog> ChangelogRevisionData<'changelog> { |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
167 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
|
168 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
|
169 let manifest_end = line_iter |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
170 .next() |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
171 .expect("Empty iterator from split()?") |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
172 .len(); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
173 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
|
174 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
|
175 })?; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
176 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
|
177 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
|
178 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
|
179 })?; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
180 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
|
181 let mut files_end = timestamp_end + 1; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
182 loop { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
183 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
|
184 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
|
185 })?; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
186 if line.is_empty() { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
187 if files_end == bytes.len() { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
188 // 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
|
189 // should be two) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
190 return Err(HgError::corrupted( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
191 "Changeset data truncated after files list", |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
192 )); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
193 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
194 files_end -= 1; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
195 break; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
196 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
197 files_end += line.len() + 1; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
198 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
199 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
200 Ok(Self { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
201 bytes, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
202 manifest_end, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
203 user_end, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
204 timestamp_end, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
205 files_end, |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
206 }) |
49063
cc132255261b
rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents:
49062
diff
changeset
|
207 } |
cc132255261b
rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents:
49062
diff
changeset
|
208 |
cc132255261b
rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents:
49062
diff
changeset
|
209 fn null() -> Self { |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
210 Self::new(Cow::Borrowed( |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
211 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
|
212 )) |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
213 .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
|
214 } |
cc132255261b
rust-changelog: remove special parsing of empty changelog data for null rev
Martin von Zweigbergk <martinvonz@google.com>
parents:
49062
diff
changeset
|
215 |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
216 /// 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
|
217 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
|
218 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
|
219 } |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
220 |
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
221 /// 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
|
222 /// entry. |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
223 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
|
224 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
|
225 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
|
226 } |
49064
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 /// 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
|
229 /// angle brackets) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
230 pub fn user(&self) -> &[u8] { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
231 &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
|
232 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
233 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
234 /// 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
|
235 /// possibly extras) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
236 // 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
|
237 pub fn timestamp_line(&self) -> &[u8] { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
238 &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
|
239 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
240 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
241 /// Parsed timestamp. |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
242 pub fn timestamp(&self) -> Result<DateTime<FixedOffset>, HgError> { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
243 parse_timestamp(self.timestamp_line()) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
244 } |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
245 |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
246 /// Optional commit extras. |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
247 pub fn extra(&self) -> Result<BTreeMap<String, Vec<u8>>, HgError> { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
248 parse_timestamp_line_extra(self.timestamp_line()) |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
249 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
250 |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
251 /// The files changed in this revision. |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
252 pub fn files(&self) -> impl Iterator<Item = &HgPath> { |
51360
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
253 if self.timestamp_end == self.files_end { |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
254 Either::Left(iter::empty()) |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
255 } else { |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
256 Either::Right( |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
257 self.bytes[self.timestamp_end + 1..self.files_end] |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
258 .split(|b| b == &b'\n') |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
259 .map(HgPath::new), |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
260 ) |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
261 } |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
262 } |
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 /// The change description. |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
265 pub fn description(&self) -> &[u8] { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
266 &self.bytes[self.files_end + 2..] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
267 } |
45532
c2317b7624fd
hg-core: add `Changlog` a specialized `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff
changeset
|
268 } |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
269 |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
270 impl Debug for ChangelogRevisionData<'_> { |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
271 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
|
272 f.debug_struct("ChangelogRevisionData") |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
273 .field("bytes", &debug_bytes(&self.bytes)) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
274 .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
|
275 .field( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
276 "user", |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
277 &debug_bytes( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
278 &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
|
279 ), |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
280 ) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
281 .field( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
282 "timestamp", |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
283 &debug_bytes( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
284 &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
|
285 ), |
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 .field( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
288 "files", |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
289 &debug_bytes( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
290 &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
|
291 ), |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
292 ) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
293 .field( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
294 "description", |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
295 &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
|
296 ) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
297 .finish() |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
298 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
299 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
300 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
301 fn debug_bytes(bytes: &[u8]) -> String { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
302 String::from_utf8_lossy( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
303 &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
|
304 ) |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
305 .to_string() |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
306 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
307 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
308 /// Parse the raw bytes of the timestamp line from a changelog entry. |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
309 /// |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
310 /// According to the documentation in `hg help dates` and the |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
311 /// implementation in `changelog.py`, the format of the timestamp line |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
312 /// is `time tz extra\n` where: |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
313 /// |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
314 /// - `time` is an ASCII-encoded signed int or float denoting a UTC timestamp |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
315 /// as seconds since the UNIX epoch. |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
316 /// |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
317 /// - `tz` is the timezone offset as an ASCII-encoded signed integer denoting |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
318 /// seconds WEST of UTC (so negative for timezones east of UTC, which is the |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
319 /// opposite of the sign in ISO 8601 timestamps). |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
320 /// |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
321 /// - `extra` is an optional set of NUL-delimited key-value pairs, with the key |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
322 /// and value in each pair separated by an ASCII colon. Keys are limited to |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
323 /// ASCII letters, digits, hyphens, and underscores, whereas values can be |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
324 /// arbitrary bytes. |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
325 fn parse_timestamp( |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
326 timestamp_line: &[u8], |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
327 ) -> Result<DateTime<FixedOffset>, HgError> { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
328 let mut parts = timestamp_line.splitn(3, |c| *c == b' '); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
329 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
330 let timestamp_bytes = parts |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
331 .next() |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
332 .ok_or_else(|| HgError::corrupted("missing timestamp"))?; |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
333 let timestamp_str = str::from_utf8(timestamp_bytes).map_err(|e| { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
334 HgError::corrupted(format!("timestamp is not valid UTF-8: {e}")) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
335 })?; |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
336 let timestamp_utc = timestamp_str |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
337 .parse() |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
338 .map_err(|e| { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
339 HgError::corrupted(format!("failed to parse timestamp: {e}")) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
340 }) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
341 .and_then(|secs| { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
342 NaiveDateTime::from_timestamp_opt(secs, 0).ok_or_else(|| { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
343 HgError::corrupted(format!( |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
344 "integer timestamp out of valid range: {secs}" |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
345 )) |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
346 }) |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
347 }) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
348 // Attempt to parse the timestamp as a float if we can't parse |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
349 // it as an int. It doesn't seem like float timestamps are actually |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
350 // used in practice, but the Python code supports them. |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
351 .or_else(|_| parse_float_timestamp(timestamp_str))?; |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
352 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
353 let timezone_bytes = parts |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
354 .next() |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
355 .ok_or_else(|| HgError::corrupted("missing timezone"))?; |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
356 let timezone_secs: i32 = str::from_utf8(timezone_bytes) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
357 .map_err(|e| { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
358 HgError::corrupted(format!("timezone is not valid UTF-8: {e}")) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
359 })? |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
360 .parse() |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
361 .map_err(|e| { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
362 HgError::corrupted(format!("timezone is not an integer: {e}")) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
363 })?; |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
364 let timezone = FixedOffset::west_opt(timezone_secs) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
365 .ok_or_else(|| HgError::corrupted("timezone offset out of bounds"))?; |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
366 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
367 Ok(DateTime::from_naive_utc_and_offset(timestamp_utc, timezone)) |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
368 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
369 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
370 /// Attempt to parse the given string as floating-point timestamp, and |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
371 /// convert the result into a `chrono::NaiveDateTime`. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
372 fn parse_float_timestamp( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
373 timestamp_str: &str, |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
374 ) -> Result<NaiveDateTime, HgError> { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
375 let timestamp = timestamp_str.parse::<f64>().map_err(|e| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
376 HgError::corrupted(format!("failed to parse timestamp: {e}")) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
377 })?; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
378 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
379 // To construct a `NaiveDateTime` we'll need to convert the float |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
380 // into signed integer seconds and unsigned integer nanoseconds. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
381 let mut secs = timestamp.trunc() as i64; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
382 let mut subsecs = timestamp.fract(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
383 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
384 // If the timestamp is negative, we need to express the fractional |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
385 // component as positive nanoseconds since the previous second. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
386 if timestamp < 0.0 { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
387 secs -= 1; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
388 subsecs += 1.0; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
389 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
390 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
391 // This cast should be safe because the fractional component is |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
392 // by definition less than 1.0, so this value should not exceed |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
393 // 1 billion, which is representable as an f64 without loss of |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
394 // precision and should fit into a u32 without overflowing. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
395 // |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
396 // (Any loss of precision in the fractional component will have |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
397 // already happened at the time of initial parsing; in general, |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
398 // f64s are insufficiently precise to provide nanosecond-level |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
399 // precision with present-day timestamps.) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
400 let nsecs = (subsecs * 1_000_000_000.0) as u32; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
401 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
402 NaiveDateTime::from_timestamp_opt(secs, nsecs).ok_or_else(|| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
403 HgError::corrupted(format!( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
404 "float timestamp out of valid range: {timestamp}" |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
405 )) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
406 }) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
407 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
408 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
409 /// Decode changeset extra fields. |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
410 /// |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
411 /// Extras are null-delimited key-value pairs where the key consists of ASCII |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
412 /// alphanumeric characters plus hyphens and underscores, and the value can |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
413 /// contain arbitrary bytes. |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
414 fn decode_extra(extra: &[u8]) -> Result<BTreeMap<String, Vec<u8>>, HgError> { |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
415 extra |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
416 .split(|c| *c == b'\0') |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
417 .map(|pair| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
418 let pair = unescape_extra(pair); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
419 let mut iter = pair.splitn(2, |c| *c == b':'); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
420 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
421 let key_bytes = |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
422 iter.next().filter(|k| !k.is_empty()).ok_or_else(|| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
423 HgError::corrupted("empty key in changeset extras") |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
424 })?; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
425 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
426 let key = str::from_utf8(key_bytes) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
427 .ok() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
428 .filter(|k| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
429 k.chars().all(|c| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
430 c.is_ascii_alphanumeric() || c == '_' || c == '-' |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
431 }) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
432 }) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
433 .ok_or_else(|| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
434 let key = String::from_utf8_lossy(key_bytes); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
435 HgError::corrupted(format!( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
436 "invalid key in changeset extras: {key}", |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
437 )) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
438 })? |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
439 .to_string(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
440 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
441 let value = iter.next().map(Into::into).ok_or_else(|| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
442 HgError::corrupted(format!( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
443 "missing value for changeset extra: {key}" |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
444 )) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
445 })?; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
446 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
447 Ok((key, value)) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
448 }) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
449 .collect() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
450 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
451 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
452 /// Parse the extra fields from a changeset's timestamp line. |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
453 fn parse_timestamp_line_extra( |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
454 timestamp_line: &[u8], |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
455 ) -> Result<BTreeMap<String, Vec<u8>>, HgError> { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
456 Ok(timestamp_line |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
457 .splitn(3, |c| *c == b' ') |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
458 .nth(2) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
459 .map(decode_extra) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
460 .transpose()? |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
461 .unwrap_or_default()) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
462 } |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
463 |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
464 /// Decode Mercurial's escaping for changelog extras. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
465 /// |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
466 /// The `_string_escape` function in `changelog.py` only escapes 4 characters |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
467 /// (null, backslash, newline, and carriage return) so we only decode those. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
468 /// |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
469 /// The Python code also includes a workaround for decoding escaped nuls |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
470 /// that are followed by an ASCII octal digit, since Python's built-in |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
471 /// `string_escape` codec will interpret that as an escaped octal byte value. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
472 /// That workaround is omitted here since we don't support decoding octal. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
473 fn unescape_extra(bytes: &[u8]) -> Vec<u8> { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
474 let mut output = Vec::with_capacity(bytes.len()); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
475 let mut input = bytes.iter().copied(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
476 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
477 while let Some(c) = input.next() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
478 if c != b'\\' { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
479 output.push(c); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
480 continue; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
481 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
482 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
483 match input.next() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
484 Some(b'0') => output.push(b'\0'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
485 Some(b'\\') => output.push(b'\\'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
486 Some(b'n') => output.push(b'\n'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
487 Some(b'r') => output.push(b'\r'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
488 // The following cases should never occur in theory because any |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
489 // backslashes in the original input should have been escaped |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
490 // with another backslash, so it should not be possible to |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
491 // observe an escape sequence other than the 4 above. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
492 Some(c) => output.extend_from_slice(&[b'\\', c]), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
493 None => output.push(b'\\'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
494 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
495 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
496 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
497 output |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
498 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
499 |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
500 #[cfg(test)] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
501 mod tests { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
502 use super::*; |
51864 | 503 use crate::vfs::VfsImpl; |
51863
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
504 use crate::{ |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
505 RevlogDataConfig, RevlogDeltaConfig, RevlogFeatureConfig, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
506 NULL_REVISION, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
507 }; |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
508 use pretty_assertions::assert_eq; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
509 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
510 #[test] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
511 fn test_create_changelogrevisiondata_invalid() { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
512 // Completely empty |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
513 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
|
514 // No newline after manifest |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
515 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
|
516 // No newline after user |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
517 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
|
518 // No newline after timestamp |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
519 assert!( |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
520 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
|
521 ); |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
522 // Missing newline after files |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
523 assert!(ChangelogRevisionData::new(Cow::Borrowed( |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
524 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
|
525 )) |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
526 .is_err(),); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
527 // Only one newline after files |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
528 assert!(ChangelogRevisionData::new(Cow::Borrowed( |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
529 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
|
530 )) |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
531 .is_err(),); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
532 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
533 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
534 #[test] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
535 fn test_create_changelogrevisiondata() { |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
536 let data = ChangelogRevisionData::new(Cow::Borrowed( |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
537 b"0123456789abcdef0123456789abcdef01234567 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
538 Some One <someone@example.com> |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
539 0 0 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
540 file1 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
541 file2 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
542 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
543 some |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
544 commit |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
545 message", |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
546 )) |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
547 .unwrap(); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
548 assert_eq!( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
549 data.manifest_node().unwrap(), |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
550 Node::from_hex("0123456789abcdef0123456789abcdef01234567") |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
551 .unwrap() |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
552 ); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
553 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
|
554 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
|
555 assert_eq!( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
556 data.files().collect_vec(), |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
557 vec![HgPath::new("file1"), HgPath::new("file2")] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
558 ); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
559 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
|
560 } |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
561 |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
562 #[test] |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
563 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:
50406
diff
changeset
|
564 // 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:
50406
diff
changeset
|
565 let temp = tempfile::tempdir().unwrap(); |
51864 | 566 let vfs = VfsImpl { |
567 base: temp.path().to_owned(), | |
568 }; | |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
569 std::fs::write(temp.path().join("foo.i"), b"").unwrap(); |
51863
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
570 std::fs::write(temp.path().join("foo.d"), b"").unwrap(); |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
571 let revlog = Revlog::open( |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
572 &vfs, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
573 "foo.i", |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
574 None, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
575 RevlogOpenOptions::new( |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
576 false, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
577 RevlogDataConfig::default(), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
578 RevlogDeltaConfig::default(), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
579 RevlogFeatureConfig::default(), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
580 ), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
581 ) |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
582 .unwrap(); |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
583 |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
584 let changelog = Changelog { revlog }; |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
585 assert_eq!( |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
586 changelog.data_for_rev(NULL_REVISION.into())?, |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
587 ChangelogRevisionData::null() |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
588 ); |
50743
124c44b5cfad
rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents:
50411
diff
changeset
|
589 // same with the intermediate entry object |
124c44b5cfad
rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents:
50411
diff
changeset
|
590 assert_eq!( |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
591 changelog.entry_for_rev(NULL_REVISION.into())?.data()?, |
50743
124c44b5cfad
rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents:
50411
diff
changeset
|
592 ChangelogRevisionData::null() |
124c44b5cfad
rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents:
50411
diff
changeset
|
593 ); |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
594 Ok(()) |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
595 } |
51360
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
596 |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
597 #[test] |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
598 fn test_empty_files_list() { |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
599 assert!(ChangelogRevisionData::null() |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
600 .files() |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
601 .collect_vec() |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
602 .is_empty()); |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
603 } |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
604 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
605 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
606 fn test_unescape_basic() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
607 // '\0', '\\', '\n', and '\r' are correctly unescaped. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
608 let expected = b"AAA\0BBB\\CCC\nDDD\rEEE"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
609 let escaped = br"AAA\0BBB\\CCC\nDDD\rEEE"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
610 let unescaped = unescape_extra(escaped); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
611 assert_eq!(&expected[..], &unescaped[..]); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
612 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
613 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
614 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
615 fn test_unescape_unsupported_sequence() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
616 // Other escape sequences are left unaltered. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
617 for c in 0u8..255 { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
618 match c { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
619 b'0' | b'\\' | b'n' | b'r' => continue, |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
620 c => { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
621 let expected = &[b'\\', c][..]; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
622 let unescaped = unescape_extra(expected); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
623 assert_eq!(expected, &unescaped[..]); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
624 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
625 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
626 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
627 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
628 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
629 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
630 fn test_unescape_trailing_backslash() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
631 // Trailing backslashes are OK. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
632 let expected = br"hi\"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
633 let unescaped = unescape_extra(expected); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
634 assert_eq!(&expected[..], &unescaped[..]); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
635 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
636 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
637 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
638 fn test_unescape_nul_followed_by_octal() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
639 // Escaped NUL chars followed by octal digits are decoded correctly. |
51703
ec7171748350
rust: apply clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51696
diff
changeset
|
640 let expected = b"\x0012"; |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
641 let escaped = br"\012"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
642 let unescaped = unescape_extra(escaped); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
643 assert_eq!(&expected[..], &unescaped[..]); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
644 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
645 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
646 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
647 fn test_parse_float_timestamp() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
648 let test_cases = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
649 // Zero should map to the UNIX epoch. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
650 ("0.0", "1970-01-01 00:00:00"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
651 // Negative zero should be the same as positive zero. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
652 ("-0.0", "1970-01-01 00:00:00"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
653 // Values without fractional components should work like integers. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
654 // (Assuming the timestamp is within the limits of f64 precision.) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
655 ("1115154970.0", "2005-05-03 21:16:10"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
656 // We expect some loss of precision in the fractional component |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
657 // when parsing arbitrary floating-point values. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
658 ("1115154970.123456789", "2005-05-03 21:16:10.123456716"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
659 // But representable f64 values should parse losslessly. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
660 ("1115154970.123456716", "2005-05-03 21:16:10.123456716"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
661 // Negative fractional components are subtracted from the epoch. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
662 ("-1.333", "1969-12-31 23:59:58.667"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
663 ]; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
664 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
665 for (input, expected) in test_cases { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
666 let res = parse_float_timestamp(input).unwrap().to_string(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
667 assert_eq!(res, expected); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
668 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
669 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
670 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
671 fn escape_extra(bytes: &[u8]) -> Vec<u8> { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
672 let mut output = Vec::with_capacity(bytes.len()); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
673 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
674 for c in bytes.iter().copied() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
675 output.extend_from_slice(match c { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
676 b'\0' => &b"\\0"[..], |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
677 b'\\' => &b"\\\\"[..], |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
678 b'\n' => &b"\\n"[..], |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
679 b'\r' => &b"\\r"[..], |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
680 _ => { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
681 output.push(c); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
682 continue; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
683 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
684 }); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
685 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
686 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
687 output |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
688 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
689 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
690 fn encode_extra<K, V>(pairs: impl IntoIterator<Item = (K, V)>) -> Vec<u8> |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
691 where |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
692 K: AsRef<[u8]>, |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
693 V: AsRef<[u8]>, |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
694 { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
695 let extras = pairs.into_iter().map(|(k, v)| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
696 escape_extra(&[k.as_ref(), b":", v.as_ref()].concat()) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
697 }); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
698 // Use fully-qualified syntax to avoid a future naming conflict with |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
699 // the standard library: https://github.com/rust-lang/rust/issues/79524 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
700 Itertools::intersperse(extras, b"\0".to_vec()).concat() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
701 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
702 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
703 #[test] |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
704 fn test_decode_extra() { |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
705 let extra = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
706 ("branch".into(), b"default".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
707 ("key-with-hyphens".into(), b"value1".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
708 ("key_with_underscores".into(), b"value2".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
709 ("empty-value".into(), b"".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
710 ("binary-value".into(), (0u8..=255).collect::<Vec<_>>()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
711 ] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
712 .into_iter() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
713 .collect::<BTreeMap<String, Vec<u8>>>(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
714 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
715 let encoded = encode_extra(&extra); |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
716 let decoded = decode_extra(&encoded).unwrap(); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
717 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
718 assert_eq!(extra, decoded); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
719 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
720 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
721 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
722 fn test_corrupt_extra() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
723 let test_cases = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
724 (&b""[..], "empty input"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
725 (&b"\0"[..], "unexpected null byte"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
726 (&b":empty-key"[..], "empty key"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
727 (&b"\0leading-null:"[..], "leading null"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
728 (&b"trailing-null:\0"[..], "trailing null"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
729 (&b"missing-value"[..], "missing value"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
730 (&b"$!@# non-alphanum-key:"[..], "non-alphanumeric key"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
731 (&b"\xF0\x9F\xA6\x80 non-ascii-key:"[..], "non-ASCII key"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
732 ]; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
733 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
734 for (extra, msg) in test_cases { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
735 assert!( |
51703
ec7171748350
rust: apply clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51696
diff
changeset
|
736 decode_extra(extra).is_err(), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
737 "corrupt extra should have failed to parse: {}", |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
738 msg |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
739 ); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
740 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
741 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
742 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
743 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
744 fn test_parse_timestamp_line() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
745 let extra = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
746 ("branch".into(), b"default".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
747 ("key-with-hyphens".into(), b"value1".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
748 ("key_with_underscores".into(), b"value2".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
749 ("empty-value".into(), b"".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
750 ("binary-value".into(), (0u8..=255).collect::<Vec<_>>()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
751 ] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
752 .into_iter() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
753 .collect::<BTreeMap<String, Vec<u8>>>(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
754 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
755 let mut line: Vec<u8> = b"1115154970 28800 ".to_vec(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
756 line.extend_from_slice(&encode_extra(&extra)); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
757 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
758 let timestamp = parse_timestamp(&line).unwrap(); |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
759 assert_eq!(×tamp.to_rfc3339(), "2005-05-03T13:16:10-08:00"); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
760 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
761 let parsed_extra = parse_timestamp_line_extra(&line).unwrap(); |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
762 assert_eq!(extra, parsed_extra); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
763 } |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
764 } |