annotate rust/hg-core/src/revlog/node.rs @ 52664:f5091286b10c

packaging: modernize (compat PEP 517) with less distutils and setup.py calls - setup.py: less distutils imports and setuptools required distutils is deprecated and one should import commands from setuptools to support modern workflows depending on PEP 517 and 518. Moreover, for Python >=3.12, distutils comes from setuptools. It corresponds to old and unmaintain code that do not support PEP 517. The PEP 517 frontends (pip, build, pipx, PDM, UV, etc.) are responsible for creating a venv just for the build. The build dependencies (currently only setuptools) are specified in the pyproject.toml file. Therefore, there is no reason to support building without setuptools. Calling directly setup.py is deprecated and we have to use a PEP 517 frontend. For this commit we use pip with venv. - run-tests.py: install with pip instead of direct call of setup.py Mercurial is then built in an isolated environment. - Makefile: use venv+pip instead of setup.py
author paugier <pierre.augier@univ-grenoble-alpes.fr>
date Wed, 08 Jan 2025 05:07:00 +0100
parents ec7171748350
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
1 // Copyright 2019-2020 Georges Racinet <georges.racinet@octobus.net>
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
2 //
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
3 // This software may be used and distributed according to the terms of the
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
4 // GNU General Public License version 2 or any later version.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
5
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
6 //! Definitions and utilities for Revision nodes
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
7 //!
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
8 //! In Mercurial code base, it is customary to call "a node" the binary SHA
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
9 //! of a revision.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
10
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
11 use crate::errors::HgError;
46391
cfb6c10c08c2 rust: replace an unsafe use of transmute with a safe use of bytes-cast
Simon Sapin <simon.sapin@octobus.net>
parents: 46033
diff changeset
12 use bytes_cast::BytesCast;
46427
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
13 use std::fmt;
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
14
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
15 /// The length in bytes of a `Node`
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
16 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
17 /// This constant is meant to ease refactors of this module, and
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
18 /// are private so that calling code does not expect all nodes have
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
19 /// the same size, should we support several formats concurrently in
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
20 /// the future.
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
21 pub const NODE_BYTES_LENGTH: usize = 20;
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
22
51186
b4d152a28742 rust-index: add append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51117
diff changeset
23 /// The length in bytes set aside on disk for a `Node`. Revlog up to v1 only
b4d152a28742 rust-index: add append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51117
diff changeset
24 /// use 20 out of those 32.
b4d152a28742 rust-index: add append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51117
diff changeset
25 pub const STORED_NODE_ID_BYTES: usize = 32;
b4d152a28742 rust-index: add append method
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51117
diff changeset
26
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
27 /// Id of the null node.
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
28 ///
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
29 /// Used to indicate the absence of node.
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
30 pub const NULL_NODE_ID: [u8; NODE_BYTES_LENGTH] = [0u8; NODE_BYTES_LENGTH];
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
31
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
32 /// The length in bytes of a `Node`
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
33 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
34 /// see also `NODES_BYTES_LENGTH` about it being private.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
35 const NODE_NYBBLES_LENGTH: usize = 2 * NODE_BYTES_LENGTH;
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
36
46744
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
37 /// Default for UI presentation
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
38 const SHORT_PREFIX_DEFAULT_NYBBLES_LENGTH: u8 = 12;
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
39
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
40 /// Private alias for readability and to ease future change
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
41 type NodeData = [u8; NODE_BYTES_LENGTH];
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
42
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
43 /// Binary revision SHA
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
44 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
45 /// ## Future changes of hash size
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
46 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
47 /// To accomodate future changes of hash size, Rust callers
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
48 /// should use the conversion methods at the boundaries (FFI, actual
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
49 /// computation of hashes and I/O) only, and only if required.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
50 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
51 /// All other callers outside of unit tests should just handle `Node` values
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
52 /// and never make any assumption on the actual length, using [`nybbles_len`]
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
53 /// if they need a loop boundary.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
54 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
55 /// All methods that create a `Node` either take a type that enforces
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
56 /// the size or return an error at runtime.
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
57 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
58 /// [`nybbles_len`]: #method.nybbles_len
49175
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
59 #[derive(Copy, Clone, PartialEq, BytesCast, derive_more::From)]
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44388
diff changeset
60 #[repr(transparent)]
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
61 pub struct Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
62 data: NodeData,
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
63 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
64
49175
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
65 impl fmt::Debug for Node {
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
67 let n = format!("{:x?}", self.data);
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
68 // We're using debug_tuple because it makes the output a little
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
69 // more compact without losing data.
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
70 f.debug_tuple("Node").field(&n).finish()
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
71 }
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
72 }
34decbaf4da3 node: manually implement Debug
Augie Fackler <augie@google.com>
parents: 48421
diff changeset
73
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
74 /// The node value for NULL_REVISION
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
75 pub const NULL_NODE: Node = Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
76 data: [0; NODE_BYTES_LENGTH],
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
77 };
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
78
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
79 /// Return an error if the slice has an unexpected length
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
80 impl<'a> TryFrom<&'a [u8]> for &'a Node {
46391
cfb6c10c08c2 rust: replace an unsafe use of transmute with a safe use of bytes-cast
Simon Sapin <simon.sapin@octobus.net>
parents: 46033
diff changeset
81 type Error = ();
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
82
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
83 #[inline]
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
84 fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
46391
cfb6c10c08c2 rust: replace an unsafe use of transmute with a safe use of bytes-cast
Simon Sapin <simon.sapin@octobus.net>
parents: 46033
diff changeset
85 match Node::from_bytes(bytes) {
51703
ec7171748350 rust: apply clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51696
diff changeset
86 Ok((node, [])) => Ok(node),
46391
cfb6c10c08c2 rust: replace an unsafe use of transmute with a safe use of bytes-cast
Simon Sapin <simon.sapin@octobus.net>
parents: 46033
diff changeset
87 _ => Err(()),
cfb6c10c08c2 rust: replace an unsafe use of transmute with a safe use of bytes-cast
Simon Sapin <simon.sapin@octobus.net>
parents: 46033
diff changeset
88 }
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
89 }
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
90 }
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
91
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
92 /// Return an error if the slice has an unexpected length
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
93 impl TryFrom<&'_ [u8]> for Node {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
94 type Error = std::array::TryFromSliceError;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
95
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
96 #[inline]
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
97 fn try_from(bytes: &'_ [u8]) -> Result<Self, Self::Error> {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
98 let data = bytes.try_into()?;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
99 Ok(Self { data })
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
100 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
101 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
102
46595
98a455a62699 rust: Make `DirstateParents`?s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
103 impl From<&'_ NodeData> for Node {
98a455a62699 rust: Make `DirstateParents`?s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
104 #[inline]
98a455a62699 rust: Make `DirstateParents`?s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
105 fn from(data: &'_ NodeData) -> Self {
98a455a62699 rust: Make `DirstateParents`?s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
106 Self { data: *data }
98a455a62699 rust: Make `DirstateParents`?s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
107 }
98a455a62699 rust: Make `DirstateParents`?s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
108 }
98a455a62699 rust: Make `DirstateParents`?s fields typed `Node`s
Simon Sapin <simon.sapin@octobus.net>
parents: 46443
diff changeset
109
46427
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
110 impl fmt::LowerHex for Node {
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
111 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
112 for &byte in &self.data {
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
113 write!(f, "{:02x}", byte)?
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
114 }
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
115 Ok(())
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
116 }
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
117 }
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
118
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
119 #[derive(Debug)]
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
120 pub struct FromHexError;
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
121
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
122 /// Low level utility function, also for prefixes
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
123 fn get_nybble(s: &[u8], i: usize) -> u8 {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
124 if i % 2 == 0 {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
125 s[i / 2] >> 4
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
126 } else {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
127 s[i / 2] & 0x0f
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
128 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
129 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
130
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
131 impl Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
132 /// Retrieve the `i`th half-byte of the binary data.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
133 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
134 /// This is also the `i`th hexadecimal digit in numeric form,
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
135 /// also called a [nybble](https://en.wikipedia.org/wiki/Nibble).
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
136 pub fn get_nybble(&self, i: usize) -> u8 {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
137 get_nybble(&self.data, i)
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
138 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
139
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
140 /// Length of the data, in nybbles
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
141 pub fn nybbles_len(&self) -> usize {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
142 // public exposure as an instance method only, so that we can
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
143 // easily support several sizes of hashes if needed in the future.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
144 NODE_NYBBLES_LENGTH
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
145 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
146
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
147 /// Convert from hexadecimal string representation
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
148 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
149 /// Exact length is required.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
150 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
151 /// To be used in FFI and I/O only, in order to facilitate future
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
152 /// changes of hash format.
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
153 pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Node, FromHexError> {
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
154 let prefix = NodePrefix::from_hex(hex)?;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
155 if prefix.nybbles_len() == NODE_NYBBLES_LENGTH {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
156 Ok(Self { data: prefix.data })
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
157 } else {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
158 Err(FromHexError)
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
159 }
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
160 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
161
46443
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
162 /// `from_hex`, but for input from an internal file of the repository such
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
163 /// as a changelog or manifest entry.
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
164 ///
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
165 /// An error is treated as repository corruption.
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
166 pub fn from_hex_for_repo(hex: impl AsRef<[u8]>) -> Result<Node, HgError> {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
167 Self::from_hex(hex.as_ref()).map_err(|FromHexError| {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
168 HgError::CorruptedRepository(format!(
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
169 "Expected a full hexadecimal node ID, found {}",
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
170 String::from_utf8_lossy(hex.as_ref())
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
171 ))
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
172 })
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
173 }
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
174
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
175 /// Provide access to binary data
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
176 ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
177 /// This is needed by FFI layers, for instance to return expected
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
178 /// binary values to Python.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
179 pub fn as_bytes(&self) -> &[u8] {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
180 &self.data
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
181 }
46744
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
182
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
183 pub fn short(&self) -> NodePrefix {
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
184 NodePrefix {
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
185 nybbles_len: SHORT_PREFIX_DEFAULT_NYBBLES_LENGTH,
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
186 data: self.data,
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
187 }
b1f2c2b336ec rhg: `cat` command: print error messages for missing files
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
188 }
48421
2097f63575a5 rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 46744
diff changeset
189
2097f63575a5 rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 46744
diff changeset
190 pub fn pad_to_256_bits(&self) -> [u8; 32] {
2097f63575a5 rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 46744
diff changeset
191 let mut bits = [0; 32];
2097f63575a5 rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 46744
diff changeset
192 bits[..NODE_BYTES_LENGTH].copy_from_slice(&self.data);
2097f63575a5 rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 46744
diff changeset
193 bits
2097f63575a5 rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 46744
diff changeset
194 }
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
195 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
196
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
197 /// The beginning of a binary revision SHA.
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
198 ///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
199 /// Since it can potentially come from an hexadecimal representation with
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
200 /// odd length, it needs to carry around whether the last 4 bits are relevant
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
201 /// or not.
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
202 #[derive(Debug, PartialEq, Copy, Clone)]
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
203 pub struct NodePrefix {
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
204 /// In `1..=NODE_NYBBLES_LENGTH`
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
205 nybbles_len: u8,
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
206 /// The first `4 * length_in_nybbles` bits are used (considering bits
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
207 /// within a bytes in big-endian: most significant first), the rest
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
208 /// are zero.
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
209 data: NodeData,
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
210 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
211
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
212 impl NodePrefix {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
213 /// Convert from hexadecimal string representation
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
214 ///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
215 /// Similarly to `hex::decode`, can be used with Unicode string types
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
216 /// (`String`, `&str`) as well as bytes.
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
217 ///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
218 /// To be used in FFI and I/O only, in order to facilitate future
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
219 /// changes of hash format.
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
220 pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Self, FromHexError> {
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
221 let hex = hex.as_ref();
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
222 let len = hex.len();
46429
e61c2dc6e1c2 rust: Exclude empty node prefixes
Simon Sapin <simon.sapin@octobus.net>
parents: 46428
diff changeset
223 if len > NODE_NYBBLES_LENGTH || len == 0 {
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
224 return Err(FromHexError);
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
225 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
226
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
227 let mut data = [0; NODE_BYTES_LENGTH];
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
228 let mut nybbles_len = 0;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
229 for &ascii_byte in hex {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
230 let nybble = match char::from(ascii_byte).to_digit(16) {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
231 Some(digit) => digit as u8,
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
232 None => return Err(FromHexError),
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
233 };
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
234 // Fill in the upper half of a byte first, then the lower half.
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
235 let shift = if nybbles_len % 2 == 0 { 4 } else { 0 };
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
236 data[nybbles_len as usize / 2] |= nybble << shift;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
237 nybbles_len += 1;
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
238 }
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
239 Ok(Self { data, nybbles_len })
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
240 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
241
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
242 pub fn nybbles_len(&self) -> usize {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
243 self.nybbles_len as _
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
244 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
245
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
246 pub fn is_prefix_of(&self, node: &Node) -> bool {
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
247 let full_bytes = self.nybbles_len() / 2;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
248 if self.data[..full_bytes] != node.data[..full_bytes] {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
249 return false;
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
250 }
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
251 if self.nybbles_len() % 2 == 0 {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
252 return true;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
253 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
254 let last = self.nybbles_len() - 1;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
255 self.get_nybble(last) == node.get_nybble(last)
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
256 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
257
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
258 /// Retrieve the `i`th half-byte from the prefix.
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
259 ///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
260 /// This is also the `i`th hexadecimal digit in numeric form,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
261 /// also called a [nybble](https://en.wikipedia.org/wiki/Nibble).
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
262 pub fn get_nybble(&self, i: usize) -> u8 {
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
263 assert!(i < self.nybbles_len());
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
264 get_nybble(&self.data, i)
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
265 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
266
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
267 fn iter_nybbles(&self) -> impl Iterator<Item = u8> + '_ {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
268 (0..self.nybbles_len()).map(move |i| get_nybble(&self.data, i))
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
269 }
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
270
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
271 /// Return the index first nybble that's different from `node`
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
272 ///
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
273 /// If the return value is `None` that means that `self` is
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
274 /// a prefix of `node`, but the current method is a bit slower
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
275 /// than `is_prefix_of`.
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
276 ///
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
277 /// Returned index is as in `get_nybble`, i.e., starting at 0.
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
278 pub fn first_different_nybble(&self, node: &Node) -> Option<usize> {
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
279 self.iter_nybbles()
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
280 .zip(NodePrefix::from(*node).iter_nybbles())
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
281 .position(|(a, b)| a != b)
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
282 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
283 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
284
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
285 impl fmt::LowerHex for NodePrefix {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
286 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
287 let full_bytes = self.nybbles_len() / 2;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
288 for &byte in &self.data[..full_bytes] {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
289 write!(f, "{:02x}", byte)?
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
290 }
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
291 if self.nybbles_len() % 2 == 1 {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
292 let last = self.nybbles_len() - 1;
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
293 write!(f, "{:x}", self.get_nybble(last))?
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
294 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
295 Ok(())
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
296 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
297 }
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
298
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
299 /// A shortcut for full `Node` references
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
300 impl From<&'_ Node> for NodePrefix {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
301 fn from(node: &'_ Node) -> Self {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
302 NodePrefix {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
303 nybbles_len: node.nybbles_len() as _,
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
304 data: node.data,
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
305 }
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
306 }
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
307 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
308
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
309 /// A shortcut for full `Node` references
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
310 impl From<Node> for NodePrefix {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
311 fn from(node: Node) -> Self {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
312 NodePrefix {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
313 nybbles_len: node.nybbles_len() as _,
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
314 data: node.data,
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
315 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
316 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
317 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
318
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
319 impl PartialEq<Node> for NodePrefix {
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
320 fn eq(&self, other: &Node) -> bool {
49927
2202832b35e8 rust-nodemap: implement `PartialEq` without allocation
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49631
diff changeset
321 self.data == other.data && self.nybbles_len() == other.nybbles_len()
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
322 }
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
323 }
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
324
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
325 #[cfg(test)]
51703
ec7171748350 rust: apply clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51696
diff changeset
326 pub use tests::hex_pad_right;
ec7171748350 rust: apply clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51696
diff changeset
327
ec7171748350 rust: apply clippy lints
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51696
diff changeset
328 #[cfg(test)]
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
329 mod tests {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
330 use super::*;
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
331
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
332 const SAMPLE_NODE_HEX: &str = "0123456789abcdeffedcba9876543210deadbeef";
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
333 const SAMPLE_NODE: Node = Node {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
334 data: [
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
335 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba,
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
336 0x98, 0x76, 0x54, 0x32, 0x10, 0xde, 0xad, 0xbe, 0xef,
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
337 ],
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
338 };
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
339
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
340 /// Pad an hexadecimal string to reach `NODE_NYBBLES_LENGTH`
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
341 /// The padding is made with zeros.
44183
e52401a95b94 rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents: 44182
diff changeset
342 pub fn hex_pad_right(hex: &str) -> String {
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
343 let mut res = hex.to_string();
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
344 while res.len() < NODE_NYBBLES_LENGTH {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
345 res.push('0');
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
346 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
347 res
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
348 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
349
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
350 #[test]
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
351 fn test_node_from_hex() {
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
352 let not_hex = "012... oops";
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
353 let too_short = "0123";
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
354 let too_long = format!("{}0", SAMPLE_NODE_HEX);
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
355 assert_eq!(Node::from_hex(SAMPLE_NODE_HEX).unwrap(), SAMPLE_NODE);
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
356 assert!(Node::from_hex(not_hex).is_err());
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
357 assert!(Node::from_hex(too_short).is_err());
51117
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49927
diff changeset
358 assert!(Node::from_hex(too_long).is_err());
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
359 }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
360
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
361 #[test]
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
362 fn test_node_encode_hex() {
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
363 assert_eq!(format!("{:x}", SAMPLE_NODE), SAMPLE_NODE_HEX);
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
364 }
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
365
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
366 #[test]
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
367 fn test_prefix_from_to_hex() -> Result<(), FromHexError> {
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
368 assert_eq!(format!("{:x}", NodePrefix::from_hex("0e1")?), "0e1");
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
369 assert_eq!(format!("{:x}", NodePrefix::from_hex("0e1a")?), "0e1a");
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
370 assert_eq!(
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
371 format!("{:x}", NodePrefix::from_hex(SAMPLE_NODE_HEX)?),
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
372 SAMPLE_NODE_HEX
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
373 );
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
374 Ok(())
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
375 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
376
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
377 #[test]
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
378 fn test_prefix_from_hex_errors() {
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
379 assert!(NodePrefix::from_hex("testgr").is_err());
46427
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
380 let mut long = format!("{:x}", NULL_NODE);
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
381 long.push('c');
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
382 assert!(NodePrefix::from_hex(&long).is_err())
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
383 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
384
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
385 #[test]
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
386 fn test_is_prefix_of() -> Result<(), FromHexError> {
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
387 let mut node_data = [0; NODE_BYTES_LENGTH];
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
388 node_data[0] = 0x12;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
389 node_data[1] = 0xca;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
390 let node = Node::from(node_data);
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
391 assert!(NodePrefix::from_hex("12")?.is_prefix_of(&node));
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
392 assert!(!NodePrefix::from_hex("1a")?.is_prefix_of(&node));
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
393 assert!(NodePrefix::from_hex("12c")?.is_prefix_of(&node));
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
394 assert!(!NodePrefix::from_hex("12d")?.is_prefix_of(&node));
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
395 Ok(())
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
396 }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
397
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
398 #[test]
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
399 fn test_get_nybble() -> Result<(), FromHexError> {
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
400 let prefix = NodePrefix::from_hex("dead6789cafe")?;
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
401 assert_eq!(prefix.get_nybble(0), 13);
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
402 assert_eq!(prefix.get_nybble(7), 9);
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
403 Ok(())
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
404 }
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
405
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
406 #[test]
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
407 fn test_first_different_nybble_even_prefix() {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
408 let prefix = NodePrefix::from_hex("12ca").unwrap();
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
409 let mut node = Node::from([0; NODE_BYTES_LENGTH]);
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
410 assert_eq!(prefix.first_different_nybble(&node), Some(0));
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
411 node.data[0] = 0x13;
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
412 assert_eq!(prefix.first_different_nybble(&node), Some(1));
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
413 node.data[0] = 0x12;
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
414 assert_eq!(prefix.first_different_nybble(&node), Some(2));
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
415 node.data[1] = 0xca;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
416 // now it is a prefix
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
417 assert_eq!(prefix.first_different_nybble(&node), None);
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
418 }
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
419
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
420 #[test]
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
421 fn test_first_different_nybble_odd_prefix() {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
422 let prefix = NodePrefix::from_hex("12c").unwrap();
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
423 let mut node = Node::from([0; NODE_BYTES_LENGTH]);
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
424 assert_eq!(prefix.first_different_nybble(&node), Some(0));
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
425 node.data[0] = 0x13;
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
426 assert_eq!(prefix.first_different_nybble(&node), Some(1));
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
427 node.data[0] = 0x12;
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
428 assert_eq!(prefix.first_different_nybble(&node), Some(2));
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
429 node.data[1] = 0xca;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
430 // now it is a prefix
46431
645ee7225fab rust: Make NodePrefix allocation-free and Copy, remove NodePrefixRef
Simon Sapin <simon.sapin@octobus.net>
parents: 46429
diff changeset
431 assert_eq!(prefix.first_different_nybble(&node), None);
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
432 }
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
433 }