Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/revlog/node.rs @ 46063:dacb771f6dd2
copies-rust: extract the processing of a ChangedFiles in its own function
This is a reasonably independent piece of code that we can extract in its own
function. This extraction will be very useful for the next changeset, where we
will change the iteration order (but still do the same kind of processing).
Differential Revision: https://phab.mercurial-scm.org/D9421
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 20 Nov 2020 14:17:08 +0100 |
parents | 88e741bf2d93 |
children | cfb6c10c08c2 |
rev | line source |
---|---|
44228
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 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
11 use hex::{self, FromHex, FromHexError}; |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
12 use std::convert::{TryFrom, TryInto}; |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
13 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
14 /// 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
|
15 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
16 /// 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
|
17 /// 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
|
18 /// 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
|
19 /// the future. |
45537
b0d6309ff50c
hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44998
diff
changeset
|
20 pub const NODE_BYTES_LENGTH: usize = 20; |
b0d6309ff50c
hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44998
diff
changeset
|
21 |
b0d6309ff50c
hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44998
diff
changeset
|
22 /// Id of the null node. |
b0d6309ff50c
hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44998
diff
changeset
|
23 /// |
b0d6309ff50c
hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44998
diff
changeset
|
24 /// Used to indicate the absence of node. |
b0d6309ff50c
hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44998
diff
changeset
|
25 pub const NULL_NODE_ID: [u8; NODE_BYTES_LENGTH] = [0u8; NODE_BYTES_LENGTH]; |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
26 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
27 /// 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
|
28 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
29 /// 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
|
30 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
|
31 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
32 /// 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
|
33 type NodeData = [u8; NODE_BYTES_LENGTH]; |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
34 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
35 /// Binary revision SHA |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
36 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
37 /// ## Future changes of hash size |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
38 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
39 /// 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
|
40 /// 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
|
41 /// 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
|
42 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
43 /// 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
|
44 /// 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
|
45 /// if they need a loop boundary. |
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 /// All methods that create a `Node` either take a type that enforces |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
48 /// the size or fail immediately at runtime with [`ExactLengthRequired`]. |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
49 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
50 /// [`nybbles_len`]: #method.nybbles_len |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
51 /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
52 #[derive(Clone, Debug, PartialEq)] |
44512
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44419
diff
changeset
|
53 #[repr(transparent)] |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
54 pub struct Node { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
55 data: NodeData, |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
56 } |
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 /// The node value for NULL_REVISION |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
59 pub const NULL_NODE: Node = Node { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
60 data: [0; NODE_BYTES_LENGTH], |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
61 }; |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
62 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
63 impl From<NodeData> for Node { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
64 fn from(data: NodeData) -> Node { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
65 Node { data } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
66 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
67 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
68 |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
69 /// 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:
45537
diff
changeset
|
70 impl<'a> TryFrom<&'a [u8]> for &'a Node { |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
71 type Error = std::array::TryFromSliceError; |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
72 |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
73 #[inline] |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
74 fn try_from(bytes: &'a [u8]) -> Result<&'a Node, Self::Error> { |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
75 let data = bytes.try_into()?; |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
76 // Safety: `#[repr(transparent)]` makes it ok to "wrap" the target |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
77 // of a reference to the type of the single field. |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
78 Ok(unsafe { std::mem::transmute::<&NodeData, &Node>(data) }) |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
79 } |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
80 } |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
81 |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
82 #[derive(Debug, PartialEq)] |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
83 pub enum NodeError { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
84 ExactLengthRequired(usize, String), |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
85 PrefixTooLong(String), |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
86 HexError(FromHexError, String), |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
87 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
88 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
89 /// 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
|
90 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
|
91 if i % 2 == 0 { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
92 s[i / 2] >> 4 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
93 } else { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
94 s[i / 2] & 0x0f |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
95 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
96 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
97 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
98 impl Node { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
99 /// 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
|
100 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
101 /// 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
|
102 /// 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
|
103 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
|
104 get_nybble(&self.data, i) |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
105 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
106 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
107 /// Length of the data, in nybbles |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
108 pub fn nybbles_len(&self) -> usize { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
109 // 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
|
110 // 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
|
111 NODE_NYBBLES_LENGTH |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
112 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
113 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
114 /// Convert from hexadecimal string representation |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
115 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
116 /// Exact length is required. |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
117 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
118 /// 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
|
119 /// changes of hash format. |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
120 pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Node, NodeError> { |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
121 Ok(NodeData::from_hex(hex.as_ref()) |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
122 .map_err(|e| NodeError::from((e, hex)))? |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
123 .into()) |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
124 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
125 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
126 /// Convert to hexadecimal string representation |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
127 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
128 /// 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
|
129 /// changes of hash format. |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
130 pub fn encode_hex(&self) -> String { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
131 hex::encode(self.data) |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
132 } |
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 /// Provide access to binary data |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
135 /// |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
136 /// 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
|
137 /// binary values to Python. |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
138 pub fn as_bytes(&self) -> &[u8] { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
139 &self.data |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
140 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
141 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
142 |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
143 impl<T: AsRef<[u8]>> From<(FromHexError, T)> for NodeError { |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
144 fn from(err_offender: (FromHexError, T)) -> Self { |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
145 let (err, offender) = err_offender; |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
146 let offender = String::from_utf8_lossy(offender.as_ref()).into_owned(); |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
147 match err { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
148 FromHexError::InvalidStringLength => { |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
149 NodeError::ExactLengthRequired(NODE_NYBBLES_LENGTH, offender) |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
150 } |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
151 _ => NodeError::HexError(err, offender), |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
152 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
153 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
154 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
155 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
156 /// The beginning of a binary revision SHA. |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
157 /// |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
158 /// Since it can potentially come from an hexadecimal representation with |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
159 /// 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:
44228
diff
changeset
|
160 /// or not. |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
161 #[derive(Debug, PartialEq)] |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
162 pub struct NodePrefix { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
163 buf: Vec<u8>, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
164 is_odd: bool, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
165 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
166 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
167 impl NodePrefix { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
168 /// Convert from hexadecimal string representation |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
169 /// |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
170 /// 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:
44228
diff
changeset
|
171 /// (`String`, `&str`) as well as bytes. |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
172 /// |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
173 /// 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:
44228
diff
changeset
|
174 /// changes of hash format. |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
175 pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Self, NodeError> { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
176 let hex = hex.as_ref(); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
177 let len = hex.len(); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
178 if len > NODE_NYBBLES_LENGTH { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
179 return Err(NodeError::PrefixTooLong( |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
180 String::from_utf8_lossy(hex).to_owned().to_string(), |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
181 )); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
182 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
183 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
184 let is_odd = len % 2 == 1; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
185 let even_part = if is_odd { &hex[..len - 1] } else { hex }; |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
186 let mut buf: Vec<u8> = |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
187 Vec::from_hex(&even_part).map_err(|e| (e, hex))?; |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
188 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
189 if is_odd { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
190 let latest_char = char::from(hex[len - 1]); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
191 let latest_nybble = latest_char.to_digit(16).ok_or_else(|| { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
192 ( |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
193 FromHexError::InvalidHexCharacter { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
194 c: latest_char, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
195 index: len - 1, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
196 }, |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
197 hex, |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
198 ) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
199 })? as u8; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
200 buf.push(latest_nybble << 4); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
201 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
202 Ok(NodePrefix { buf, is_odd }) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
203 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
204 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
205 pub fn borrow(&self) -> NodePrefixRef { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
206 NodePrefixRef { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
207 buf: &self.buf, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
208 is_odd: self.is_odd, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
209 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
210 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
211 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
212 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
213 #[derive(Clone, Debug, PartialEq)] |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
214 pub struct NodePrefixRef<'a> { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
215 buf: &'a [u8], |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
216 is_odd: bool, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
217 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
218 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
219 impl<'a> NodePrefixRef<'a> { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
220 pub fn len(&self) -> usize { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
221 if self.is_odd { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
222 self.buf.len() * 2 - 1 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
223 } else { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
224 self.buf.len() * 2 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
225 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
226 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
227 |
44998
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
228 pub fn is_empty(&self) -> bool { |
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
229 self.len() == 0 |
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
230 } |
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
231 |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
232 pub fn is_prefix_of(&self, node: &Node) -> bool { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
233 if self.is_odd { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
234 let buf = self.buf; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
235 let last_pos = buf.len() - 1; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
236 node.data.starts_with(buf.split_at(last_pos).0) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
237 && node.data[last_pos] >> 4 == buf[last_pos] >> 4 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
238 } else { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
239 node.data.starts_with(self.buf) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
240 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
241 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
242 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
243 /// Retrieve the `i`th half-byte from the prefix. |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
244 /// |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
245 /// 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:
44228
diff
changeset
|
246 /// also called a [nybble](https://en.wikipedia.org/wiki/Nibble). |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
247 pub fn get_nybble(&self, i: usize) -> u8 { |
44262
be52b7372ec2
rust-node: avoid meaningless read at the end of odd prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44258
diff
changeset
|
248 assert!(i < self.len()); |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
249 get_nybble(self.buf, i) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
250 } |
44419
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
251 |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
252 /// Return the index first nybble that's different from `node` |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
253 /// |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
254 /// 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:
44262
diff
changeset
|
255 /// 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:
44262
diff
changeset
|
256 /// than `is_prefix_of`. |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
257 /// |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
258 /// 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:
44262
diff
changeset
|
259 pub fn first_different_nybble(&self, node: &Node) -> Option<usize> { |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
260 let buf = self.buf; |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
261 let until = if self.is_odd { |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
262 buf.len() - 1 |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
263 } else { |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
264 buf.len() |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
265 }; |
44998
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
266 for (i, item) in buf.iter().enumerate().take(until) { |
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
267 if *item != node.data[i] { |
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
268 return if *item & 0xf0 == node.data[i] & 0xf0 { |
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
269 Some(2 * i + 1) |
44419
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
270 } else { |
44998
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
271 Some(2 * i) |
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44512
diff
changeset
|
272 }; |
44419
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
273 } |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
274 } |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
275 if self.is_odd && buf[until] & 0xf0 != node.data[until] & 0xf0 { |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
276 Some(until * 2) |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
277 } else { |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
278 None |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
279 } |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
280 } |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
281 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
282 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
283 /// A shortcut for full `Node` references |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
284 impl<'a> From<&'a Node> for NodePrefixRef<'a> { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
285 fn from(node: &'a Node) -> Self { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
286 NodePrefixRef { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
287 buf: &node.data, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
288 is_odd: false, |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
289 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
290 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
291 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
292 |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
293 impl PartialEq<Node> for NodePrefixRef<'_> { |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
294 fn eq(&self, other: &Node) -> bool { |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
295 !self.is_odd && self.buf == other.data |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
296 } |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
297 } |
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
298 |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
299 #[cfg(test)] |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
300 mod tests { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
301 use super::*; |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
302 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
303 fn sample_node() -> Node { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
304 let mut data = [0; NODE_BYTES_LENGTH]; |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
305 data.copy_from_slice(&[ |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
306 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
|
307 0x98, 0x76, 0x54, 0x32, 0x10, 0xde, 0xad, 0xbe, 0xef, |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
308 ]); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
309 data.into() |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
310 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
311 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
312 /// Pad an hexadecimal string to reach `NODE_NYBBLES_LENGTH` |
46037
88e741bf2d93
rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents:
45537
diff
changeset
|
313 ///check_hash |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
314 /// The padding is made with zeros |
44258
e52401a95b94
rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
44257
diff
changeset
|
315 pub fn hex_pad_right(hex: &str) -> String { |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
316 let mut res = hex.to_string(); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
317 while res.len() < NODE_NYBBLES_LENGTH { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
318 res.push('0'); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
319 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
320 res |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
321 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
322 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
323 fn sample_node_hex() -> String { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
324 hex_pad_right("0123456789abcdeffedcba9876543210deadbeef") |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
325 } |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
326 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
327 #[test] |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
328 fn test_node_from_hex() { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
329 assert_eq!(Node::from_hex(&sample_node_hex()), Ok(sample_node())); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
330 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
331 let mut short = hex_pad_right("0123"); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
332 short.pop(); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
333 short.pop(); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
334 assert_eq!( |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
335 Node::from_hex(&short), |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
336 Err(NodeError::ExactLengthRequired(NODE_NYBBLES_LENGTH, short)), |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
337 ); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
338 |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
339 let not_hex = hex_pad_right("012... oops"); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
340 assert_eq!( |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
341 Node::from_hex(¬_hex), |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
342 Err(NodeError::HexError( |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
343 FromHexError::InvalidHexCharacter { c: '.', index: 3 }, |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
344 not_hex, |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
345 )), |
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 } |
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 #[test] |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
350 fn test_node_encode_hex() { |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
351 assert_eq!(sample_node().encode_hex(), sample_node_hex()); |
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
352 } |
44257
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
353 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
354 #[test] |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
355 fn test_prefix_from_hex() -> Result<(), NodeError> { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
356 assert_eq!( |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
357 NodePrefix::from_hex("0e1")?, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
358 NodePrefix { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
359 buf: vec![14, 16], |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
360 is_odd: true |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
361 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
362 ); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
363 assert_eq!( |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
364 NodePrefix::from_hex("0e1a")?, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
365 NodePrefix { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
366 buf: vec![14, 26], |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
367 is_odd: false |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
368 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
369 ); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
370 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
371 // checking limit case |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
372 let node_as_vec = sample_node().data.iter().cloned().collect(); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
373 assert_eq!( |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
374 NodePrefix::from_hex(sample_node_hex())?, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
375 NodePrefix { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
376 buf: node_as_vec, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
377 is_odd: false |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
378 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
379 ); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
380 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
381 Ok(()) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
382 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
383 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
384 #[test] |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
385 fn test_prefix_from_hex_errors() { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
386 assert_eq!( |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
387 NodePrefix::from_hex("testgr"), |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
388 Err(NodeError::HexError( |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
389 FromHexError::InvalidHexCharacter { c: 't', index: 0 }, |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
390 "testgr".to_string() |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
391 )) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
392 ); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
393 let mut long = NULL_NODE.encode_hex(); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
394 long.push('c'); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
395 match NodePrefix::from_hex(&long) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
396 .expect_err("should be refused as too long") |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
397 { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
398 NodeError::PrefixTooLong(s) => assert_eq!(s, long), |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
399 err => panic!(format!("Should have been TooLong, got {:?}", err)), |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
400 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
401 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
402 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
403 #[test] |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
404 fn test_is_prefix_of() -> Result<(), NodeError> { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
405 let mut node_data = [0; NODE_BYTES_LENGTH]; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
406 node_data[0] = 0x12; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
407 node_data[1] = 0xca; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
408 let node = Node::from(node_data); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
409 assert!(NodePrefix::from_hex("12")?.borrow().is_prefix_of(&node)); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
410 assert!(!NodePrefix::from_hex("1a")?.borrow().is_prefix_of(&node)); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
411 assert!(NodePrefix::from_hex("12c")?.borrow().is_prefix_of(&node)); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
412 assert!(!NodePrefix::from_hex("12d")?.borrow().is_prefix_of(&node)); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
413 Ok(()) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
414 } |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
415 |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
416 #[test] |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
417 fn test_get_nybble() -> Result<(), NodeError> { |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
418 let prefix = NodePrefix::from_hex("dead6789cafe")?; |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
419 assert_eq!(prefix.borrow().get_nybble(0), 13); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
420 assert_eq!(prefix.borrow().get_nybble(7), 9); |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
421 Ok(()) |
9896a8d0d3d2
rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents:
44228
diff
changeset
|
422 } |
44419
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
423 |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
424 #[test] |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
425 fn test_first_different_nybble_even_prefix() { |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
426 let prefix = NodePrefix::from_hex("12ca").unwrap(); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
427 let prefref = prefix.borrow(); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
428 let mut node = Node::from([0; NODE_BYTES_LENGTH]); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
429 assert_eq!(prefref.first_different_nybble(&node), Some(0)); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
430 node.data[0] = 0x13; |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
431 assert_eq!(prefref.first_different_nybble(&node), Some(1)); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
432 node.data[0] = 0x12; |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
433 assert_eq!(prefref.first_different_nybble(&node), Some(2)); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
434 node.data[1] = 0xca; |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
435 // now it is a prefix |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
436 assert_eq!(prefref.first_different_nybble(&node), None); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
437 } |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
438 |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
439 #[test] |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
440 fn test_first_different_nybble_odd_prefix() { |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
441 let prefix = NodePrefix::from_hex("12c").unwrap(); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
442 let prefref = prefix.borrow(); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
443 let mut node = Node::from([0; NODE_BYTES_LENGTH]); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
444 assert_eq!(prefref.first_different_nybble(&node), Some(0)); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
445 node.data[0] = 0x13; |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
446 assert_eq!(prefref.first_different_nybble(&node), Some(1)); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
447 node.data[0] = 0x12; |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
448 assert_eq!(prefref.first_different_nybble(&node), Some(2)); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
449 node.data[1] = 0xca; |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
450 // now it is a prefix |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
451 assert_eq!(prefref.first_different_nybble(&node), None); |
5ac1eecc9c64
rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents:
44262
diff
changeset
|
452 } |
44228
7f86426fdd2c
rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
453 } |
44258
e52401a95b94
rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
44257
diff
changeset
|
454 |
e52401a95b94
rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
44257
diff
changeset
|
455 #[cfg(test)] |
e52401a95b94
rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
44257
diff
changeset
|
456 pub use tests::hex_pad_right; |