Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/revlog/changelog.rs @ 52186:e6a44bc91bc2 stable
rust-update: make `update_from_null` respect `worker.numcpu` config option
This was overlooked in the original series.
This is important for tests (because we run many at once), and for the
occasional end user that wants to keep their CPU usage in check.
A future series should clean up this `worker` parameter tunelling business by
rewriting the config in Rust, but doing so on stable would be a very bad
idea.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Tue, 05 Nov 2024 15:21:09 +0100 |
parents | 1d6982827c4b |
children | 039b7caeb4d9 |
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 |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
7 use chrono::{DateTime, FixedOffset, Utc}; |
51388
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| { |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
342 DateTime::from_timestamp(secs, 0).ok_or_else(|| { |
51390
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 |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
367 Ok(DateTime::from_naive_utc_and_offset( |
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
368 timestamp_utc.naive_utc(), |
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
369 timezone, |
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
370 )) |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
371 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
372 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
373 /// 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
|
374 /// convert the result into a `chrono::NaiveDateTime`. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
375 fn parse_float_timestamp( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
376 timestamp_str: &str, |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
377 ) -> Result<DateTime<Utc>, HgError> { |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
378 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
|
379 HgError::corrupted(format!("failed to parse timestamp: {e}")) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
380 })?; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
381 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
382 // 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
|
383 // into signed integer seconds and unsigned integer nanoseconds. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
384 let mut secs = timestamp.trunc() as i64; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
385 let mut subsecs = timestamp.fract(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
386 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
387 // 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
|
388 // component as positive nanoseconds since the previous second. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
389 if timestamp < 0.0 { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
390 secs -= 1; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
391 subsecs += 1.0; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
392 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
393 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
394 // 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
|
395 // 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
|
396 // 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
|
397 // 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
|
398 // |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
399 // (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
|
400 // 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
|
401 // f64s are insufficiently precise to provide nanosecond-level |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
402 // precision with present-day timestamps.) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
403 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
|
404 |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
405 DateTime::from_timestamp(secs, nsecs).ok_or_else(|| { |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
406 HgError::corrupted(format!( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
407 "float timestamp out of valid range: {timestamp}" |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
408 )) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
409 }) |
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 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
412 /// Decode changeset extra fields. |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
413 /// |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
414 /// 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
|
415 /// 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
|
416 /// contain arbitrary bytes. |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
417 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
|
418 extra |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
419 .split(|c| *c == b'\0') |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
420 .map(|pair| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
421 let pair = unescape_extra(pair); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
422 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
|
423 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
424 let key_bytes = |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
425 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
|
426 HgError::corrupted("empty key in changeset extras") |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
427 })?; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
428 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
429 let key = str::from_utf8(key_bytes) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
430 .ok() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
431 .filter(|k| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
432 k.chars().all(|c| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
433 c.is_ascii_alphanumeric() || c == '_' || c == '-' |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
434 }) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
435 }) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
436 .ok_or_else(|| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
437 let key = String::from_utf8_lossy(key_bytes); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
438 HgError::corrupted(format!( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
439 "invalid key in changeset extras: {key}", |
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 })? |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
442 .to_string(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
443 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
444 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
|
445 HgError::corrupted(format!( |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
446 "missing value for changeset extra: {key}" |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
447 )) |
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 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
450 Ok((key, value)) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
451 }) |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
452 .collect() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
453 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
454 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
455 /// 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
|
456 fn parse_timestamp_line_extra( |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
457 timestamp_line: &[u8], |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
458 ) -> Result<BTreeMap<String, Vec<u8>>, HgError> { |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
459 Ok(timestamp_line |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
460 .splitn(3, |c| *c == b' ') |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
461 .nth(2) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
462 .map(decode_extra) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
463 .transpose()? |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
464 .unwrap_or_default()) |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
465 } |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
466 |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
467 /// Decode Mercurial's escaping for changelog extras. |
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 `_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
|
470 /// (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
|
471 /// |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
472 /// 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
|
473 /// 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
|
474 /// `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
|
475 /// 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
|
476 fn unescape_extra(bytes: &[u8]) -> Vec<u8> { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
477 let mut output = Vec::with_capacity(bytes.len()); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
478 let mut input = bytes.iter().copied(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
479 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
480 while let Some(c) = input.next() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
481 if c != b'\\' { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
482 output.push(c); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
483 continue; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
484 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
485 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
486 match input.next() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
487 Some(b'0') => output.push(b'\0'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
488 Some(b'\\') => output.push(b'\\'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
489 Some(b'n') => output.push(b'\n'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
490 Some(b'r') => output.push(b'\r'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
491 // 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
|
492 // 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
|
493 // 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
|
494 // 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
|
495 Some(c) => output.extend_from_slice(&[b'\\', c]), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
496 None => output.push(b'\\'), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
497 } |
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 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
500 output |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
501 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
502 |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
503 #[cfg(test)] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
504 mod tests { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
505 use super::*; |
51864 | 506 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
|
507 use crate::{ |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
508 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
|
509 NULL_REVISION, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
510 }; |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
511 use pretty_assertions::assert_eq; |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
512 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
513 #[test] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
514 fn test_create_changelogrevisiondata_invalid() { |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
515 // Completely empty |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
516 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
|
517 // No newline after manifest |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
518 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
|
519 // No newline after user |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
520 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
|
521 // No newline after timestamp |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
522 assert!( |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
523 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
|
524 ); |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
525 // Missing newline after files |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
526 assert!(ChangelogRevisionData::new(Cow::Borrowed( |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
527 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
|
528 )) |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
529 .is_err(),); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
530 // Only one newline after files |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
531 assert!(ChangelogRevisionData::new(Cow::Borrowed( |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
532 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
|
533 )) |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
534 .is_err(),); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
535 } |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
536 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
537 #[test] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
538 fn test_create_changelogrevisiondata() { |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
539 let data = ChangelogRevisionData::new(Cow::Borrowed( |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
540 b"0123456789abcdef0123456789abcdef01234567 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
541 Some One <someone@example.com> |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
542 0 0 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
543 file1 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
544 file2 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
545 |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
546 some |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
547 commit |
49096
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
548 message", |
07ec9f4f24bf
changelog: avoid copying changeset data into `ChangesetRevisionData`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
549 )) |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
550 .unwrap(); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
551 assert_eq!( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
552 data.manifest_node().unwrap(), |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
553 Node::from_hex("0123456789abcdef0123456789abcdef01234567") |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
554 .unwrap() |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
555 ); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
556 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
|
557 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
|
558 assert_eq!( |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
559 data.files().collect_vec(), |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
560 vec![HgPath::new("file1"), HgPath::new("file2")] |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
561 ); |
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
562 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
|
563 } |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
564 |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
565 #[test] |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
566 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
|
567 // 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
|
568 let temp = tempfile::tempdir().unwrap(); |
51864 | 569 let vfs = VfsImpl { |
570 base: temp.path().to_owned(), | |
571 }; | |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
572 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
|
573 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
|
574 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
|
575 &vfs, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
576 "foo.i", |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
577 None, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
578 RevlogOpenOptions::new( |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
579 false, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
580 RevlogDataConfig::default(), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
581 RevlogDeltaConfig::default(), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
582 RevlogFeatureConfig::default(), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
583 ), |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
584 ) |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51721
diff
changeset
|
585 .unwrap(); |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
586 |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
587 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
|
588 assert_eq!( |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
589 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
|
590 ChangelogRevisionData::null() |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
591 ); |
50743
124c44b5cfad
rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents:
50411
diff
changeset
|
592 // 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
|
593 assert_eq!( |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50744
diff
changeset
|
594 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
|
595 ChangelogRevisionData::null() |
124c44b5cfad
rust-revlog: fix RevlogEntry.data() for NULL_REVISION
Georges Racinet <georges.racinet@octobus.net>
parents:
50411
diff
changeset
|
596 ); |
50407
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
597 Ok(()) |
b5dd6d6d6fa6
rust-changelog: added a test for `NULL_REVISION` special case
Georges Racinet <georges.racinet@octobus.net>
parents:
50406
diff
changeset
|
598 } |
51360
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
599 |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
600 #[test] |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
601 fn test_empty_files_list() { |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
602 assert!(ChangelogRevisionData::null() |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
603 .files() |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
604 .collect_vec() |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
605 .is_empty()); |
d626e5e7bbbe
rust-changelog: don't panic on empty file lists
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
50975
diff
changeset
|
606 } |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
607 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
608 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
609 fn test_unescape_basic() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
610 // '\0', '\\', '\n', and '\r' are correctly unescaped. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
611 let expected = b"AAA\0BBB\\CCC\nDDD\rEEE"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
612 let escaped = br"AAA\0BBB\\CCC\nDDD\rEEE"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
613 let unescaped = unescape_extra(escaped); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
614 assert_eq!(&expected[..], &unescaped[..]); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
615 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
616 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
617 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
618 fn test_unescape_unsupported_sequence() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
619 // Other escape sequences are left unaltered. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
620 for c in 0u8..255 { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
621 match c { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
622 b'0' | b'\\' | b'n' | b'r' => continue, |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
623 c => { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
624 let expected = &[b'\\', c][..]; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
625 let unescaped = unescape_extra(expected); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
626 assert_eq!(expected, &unescaped[..]); |
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 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
630 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
631 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
632 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
633 fn test_unescape_trailing_backslash() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
634 // Trailing backslashes are OK. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
635 let expected = br"hi\"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
636 let unescaped = unescape_extra(expected); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
637 assert_eq!(&expected[..], &unescaped[..]); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
638 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
639 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
640 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
641 fn test_unescape_nul_followed_by_octal() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
642 // 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
|
643 let expected = b"\x0012"; |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
644 let escaped = br"\012"; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
645 let unescaped = unescape_extra(escaped); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
646 assert_eq!(&expected[..], &unescaped[..]); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
647 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
648 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
649 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
650 fn test_parse_float_timestamp() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
651 let test_cases = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
652 // Zero should map to the UNIX epoch. |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
653 ("0.0", "1970-01-01 00:00:00 UTC"), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
654 // Negative zero should be the same as positive zero. |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
655 ("-0.0", "1970-01-01 00:00:00 UTC"), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
656 // Values without fractional components should work like integers. |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
657 // (Assuming the timestamp is within the limits of f64 precision.) |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
658 ("1115154970.0", "2005-05-03 21:16:10 UTC"), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
659 // 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
|
660 // when parsing arbitrary floating-point values. |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
661 ("1115154970.123456789", "2005-05-03 21:16:10.123456716 UTC"), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
662 // But representable f64 values should parse losslessly. |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
663 ("1115154970.123456716", "2005-05-03 21:16:10.123456716 UTC"), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
664 // Negative fractional components are subtracted from the epoch. |
51913
1d6982827c4b
rust: fix the deprecation warning in NaiveDateTime::from_timestamp
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
51864
diff
changeset
|
665 ("-1.333", "1969-12-31 23:59:58.667 UTC"), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
666 ]; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
667 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
668 for (input, expected) in test_cases { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
669 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
|
670 assert_eq!(res, expected); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
671 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
672 } |
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 fn escape_extra(bytes: &[u8]) -> Vec<u8> { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
675 let mut output = Vec::with_capacity(bytes.len()); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
676 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
677 for c in bytes.iter().copied() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
678 output.extend_from_slice(match c { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
679 b'\0' => &b"\\0"[..], |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
680 b'\\' => &b"\\\\"[..], |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
681 b'\n' => &b"\\n"[..], |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
682 b'\r' => &b"\\r"[..], |
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 output.push(c); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
685 continue; |
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 }); |
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 output |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
691 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
692 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
693 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
|
694 where |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
695 K: AsRef<[u8]>, |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
696 V: AsRef<[u8]>, |
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 let extras = pairs.into_iter().map(|(k, v)| { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
699 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
|
700 }); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
701 // 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
|
702 // 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
|
703 Itertools::intersperse(extras, b"\0".to_vec()).concat() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
704 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
705 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
706 #[test] |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
707 fn test_decode_extra() { |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
708 let extra = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
709 ("branch".into(), b"default".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
710 ("key-with-hyphens".into(), b"value1".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
711 ("key_with_underscores".into(), b"value2".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
712 ("empty-value".into(), b"".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
713 ("binary-value".into(), (0u8..=255).collect::<Vec<_>>()), |
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 .into_iter() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
716 .collect::<BTreeMap<String, Vec<u8>>>(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
717 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
718 let encoded = encode_extra(&extra); |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
719 let decoded = decode_extra(&encoded).unwrap(); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
720 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
721 assert_eq!(extra, decoded); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
722 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
723 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
724 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
725 fn test_corrupt_extra() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
726 let test_cases = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
727 (&b""[..], "empty input"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
728 (&b"\0"[..], "unexpected null byte"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
729 (&b":empty-key"[..], "empty key"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
730 (&b"\0leading-null:"[..], "leading null"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
731 (&b"trailing-null:\0"[..], "trailing null"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
732 (&b"missing-value"[..], "missing value"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
733 (&b"$!@# non-alphanum-key:"[..], "non-alphanumeric key"), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
734 (&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
|
735 ]; |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
736 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
737 for (extra, msg) in test_cases { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
738 assert!( |
51703
ec7171748350
rust: apply clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51696
diff
changeset
|
739 decode_extra(extra).is_err(), |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
740 "corrupt extra should have failed to parse: {}", |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
741 msg |
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 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
744 } |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
745 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
746 #[test] |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
747 fn test_parse_timestamp_line() { |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
748 let extra = [ |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
749 ("branch".into(), b"default".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
750 ("key-with-hyphens".into(), b"value1".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
751 ("key_with_underscores".into(), b"value2".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
752 ("empty-value".into(), b"".to_vec()), |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
753 ("binary-value".into(), (0u8..=255).collect::<Vec<_>>()), |
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 .into_iter() |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
756 .collect::<BTreeMap<String, Vec<u8>>>(); |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
757 |
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
758 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
|
759 line.extend_from_slice(&encode_extra(&extra)); |
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 timestamp = parse_timestamp(&line).unwrap(); |
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
762 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
|
763 |
51390
6603a1448f18
hg-core: separate timestamp and extra methods
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51388
diff
changeset
|
764 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
|
765 assert_eq!(extra, parsed_extra); |
51388
a96ed440450e
hg-core: implement timestamp line parsing
Arun Kulshreshtha <akulshreshtha@janestreet.com>
parents:
51366
diff
changeset
|
766 } |
49064
95da3e99cbd8
rust-changelog: start parsing changeset data
Martin von Zweigbergk <martinvonz@google.com>
parents:
49063
diff
changeset
|
767 } |