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