rust/hg-core/src/revlog/node.rs
author Simon Sapin <simon.sapin@octobus.net>
Mon, 25 Jan 2021 12:31:40 +0100
changeset 46429 e61c2dc6e1c2
parent 46428 5893706af3de
child 46431 645ee7225fab
permissions -rw-r--r--
rust: Exclude empty node prefixes We presumably don’t want `--rev ""` to select every single revision, even though the empty string is a prefix of all strings. Differential Revision: https://phab.mercurial-scm.org/D9862
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
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
    11
use bytes_cast::BytesCast;
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
    12
use hex::{self, FromHex};
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
    13
use std::convert::TryFrom;
46427
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
    14
use std::fmt;
44143
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
/// 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
    17
///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    18
/// 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
    19
/// 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
    20
/// 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
    21
/// the future.
45531
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
    22
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
    23
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
    24
/// Id of the null node.
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
    25
///
b0d6309ff50c hg-core: check data integrity in `Revlog`
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
    26
/// 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
    27
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
    28
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    29
/// 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
    30
///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    31
/// 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
    32
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
    33
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    34
/// 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
    35
type NodeData = [u8; NODE_BYTES_LENGTH];
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
/// Binary revision SHA
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
/// ## Future changes of hash size
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    40
///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    41
/// 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
    42
/// 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
    43
/// 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
    44
///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    45
/// 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
    46
/// 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
    47
/// if they need a loop boundary.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    48
///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    49
/// 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
    50
/// 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
    51
///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    52
/// [`nybbles_len`]: #method.nybbles_len
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
    53
#[derive(Clone, Debug, PartialEq, BytesCast)]
44502
166349510398 revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents: 44388
diff changeset
    54
#[repr(transparent)]
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    55
pub struct Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    56
    data: NodeData,
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
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    59
/// The node value for NULL_REVISION
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    60
pub const NULL_NODE: Node = Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    61
    data: [0; NODE_BYTES_LENGTH],
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
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    64
impl From<NodeData> for Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    65
    fn from(data: NodeData) -> Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    66
        Node { data }
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
}
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    69
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
    70
/// 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
    71
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
    72
    type Error = ();
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
    73
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
    74
    #[inline]
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
    75
    fn try_from(bytes: &'a [u8]) -> Result<&'a Node, 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
    76
        match Node::from_bytes(bytes) {
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
    77
            Ok((node, rest)) if rest.is_empty() => Ok(node),
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
    78
            _ => 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
    79
        }
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
    80
    }
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
    81
}
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
    82
46427
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
    83
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
    84
    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
    85
        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
    86
            write!(f, "{:02x}", byte)?
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
    87
        }
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
    88
        Ok(())
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
    89
    }
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
    90
}
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
    91
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
    92
#[derive(Debug)]
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
    93
pub struct FromHexError;
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    94
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    95
/// 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
    96
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
    97
    if i % 2 == 0 {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    98
        s[i / 2] >> 4
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    99
    } else {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   100
        s[i / 2] & 0x0f
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   101
    }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   102
}
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   103
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   104
impl Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   105
    /// 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
   106
    ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   107
    /// 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
   108
    /// 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
   109
    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
   110
        get_nybble(&self.data, i)
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   111
    }
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
    /// Length of the data, in nybbles
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   114
    pub fn nybbles_len(&self) -> usize {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   115
        // 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
   116
        // 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
   117
        NODE_NYBBLES_LENGTH
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   118
    }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   119
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   120
    /// Convert from hexadecimal string representation
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
    /// Exact length is required.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   123
    ///
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   124
    /// 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
   125
    /// 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
   126
    pub fn from_hex(hex: impl AsRef<[u8]>) -> Result<Node, FromHexError> {
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   127
        Ok(NodeData::from_hex(hex.as_ref())
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   128
            .map_err(|_| FromHexError)?
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   129
            .into())
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
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   132
    /// Provide access to 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 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
   135
    /// binary values to Python.
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   136
    pub fn as_bytes(&self) -> &[u8] {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   137
        &self.data
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
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   141
/// The beginning of a binary revision SHA.
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   142
///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   143
/// 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
   144
/// 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
   145
/// or not.
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   146
#[derive(Debug, PartialEq)]
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   147
pub struct NodePrefix {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   148
    buf: Vec<u8>,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   149
    is_odd: bool,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   150
}
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   151
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   152
impl NodePrefix {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   153
    /// Convert from hexadecimal string representation
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   154
    ///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   155
    /// 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
   156
    /// (`String`, `&str`) as well as bytes.
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   157
    ///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   158
    /// 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
   159
    /// 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
   160
    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
   161
        let hex = hex.as_ref();
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   162
        let len = hex.len();
46429
e61c2dc6e1c2 rust: Exclude empty node prefixes
Simon Sapin <simon.sapin@octobus.net>
parents: 46428
diff changeset
   163
        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
   164
            return Err(FromHexError);
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   165
        }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   166
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   167
        let is_odd = len % 2 == 1;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   168
        let even_part = if is_odd { &hex[..len - 1] } else { hex };
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   169
        let mut buf: Vec<u8> =
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   170
            Vec::from_hex(&even_part).map_err(|_| FromHexError)?;
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   171
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   172
        if is_odd {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   173
            let latest_char = char::from(hex[len - 1]);
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   174
            let latest_nybble =
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   175
                latest_char.to_digit(16).ok_or_else(|| FromHexError)? as u8;
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   176
            buf.push(latest_nybble << 4);
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   177
        }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   178
        Ok(NodePrefix { buf, is_odd })
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   179
    }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   180
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   181
    pub fn borrow(&self) -> NodePrefixRef {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   182
        NodePrefixRef {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   183
            buf: &self.buf,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   184
            is_odd: self.is_odd,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   185
        }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   186
    }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   187
}
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   188
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   189
#[derive(Clone, Debug, PartialEq)]
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   190
pub struct NodePrefixRef<'a> {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   191
    buf: &'a [u8],
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   192
    is_odd: bool,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   193
}
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   194
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   195
impl<'a> NodePrefixRef<'a> {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   196
    pub fn len(&self) -> usize {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   197
        if self.is_odd {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   198
            self.buf.len() * 2 - 1
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   199
        } else {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   200
            self.buf.len() * 2
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   201
        }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   202
    }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   203
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   204
    pub fn is_prefix_of(&self, node: &Node) -> bool {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   205
        if self.is_odd {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   206
            let buf = self.buf;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   207
            let last_pos = buf.len() - 1;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   208
            node.data.starts_with(buf.split_at(last_pos).0)
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   209
                && node.data[last_pos] >> 4 == buf[last_pos] >> 4
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   210
        } else {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   211
            node.data.starts_with(self.buf)
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   212
        }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   213
    }
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
    /// 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
   216
    ///
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   217
    /// 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
   218
    /// 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
   219
    pub fn get_nybble(&self, i: usize) -> u8 {
44187
be52b7372ec2 rust-node: avoid meaningless read at the end of odd prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44183
diff changeset
   220
        assert!(i < self.len());
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   221
        get_nybble(self.buf, i)
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   222
    }
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   223
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   224
    /// 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
   225
    ///
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   226
    /// 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
   227
    /// 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
   228
    /// than `is_prefix_of`.
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   229
    ///
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   230
    /// 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
   231
    pub fn first_different_nybble(&self, node: &Node) -> Option<usize> {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   232
        let buf = self.buf;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   233
        let until = if self.is_odd {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   234
            buf.len() - 1
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   235
        } else {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   236
            buf.len()
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   237
        };
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44502
diff changeset
   238
        for (i, item) in buf.iter().enumerate().take(until) {
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44502
diff changeset
   239
            if *item != node.data[i] {
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44502
diff changeset
   240
                return if *item & 0xf0 == node.data[i] & 0xf0 {
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44502
diff changeset
   241
                    Some(2 * i + 1)
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   242
                } else {
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44502
diff changeset
   243
                    Some(2 * i)
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44502
diff changeset
   244
                };
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   245
            }
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   246
        }
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   247
        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: 44187
diff changeset
   248
            Some(until * 2)
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   249
        } else {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   250
            None
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   251
        }
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   252
    }
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   253
}
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   254
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   255
/// A shortcut for full `Node` references
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   256
impl<'a> From<&'a Node> for NodePrefixRef<'a> {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   257
    fn from(node: &'a Node) -> Self {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   258
        NodePrefixRef {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   259
            buf: &node.data,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   260
            is_odd: false,
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   261
        }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   262
    }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   263
}
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   264
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   265
impl PartialEq<Node> for NodePrefixRef<'_> {
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   266
    fn eq(&self, other: &Node) -> bool {
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   267
        !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: 45531
diff changeset
   268
    }
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   269
}
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   270
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   271
#[cfg(test)]
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   272
mod tests {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   273
    use super::*;
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   274
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   275
    fn sample_node() -> Node {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   276
        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
   277
        data.copy_from_slice(&[
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   278
            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
   279
            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
   280
        ]);
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   281
        data.into()
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   282
    }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   283
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   284
    /// Pad an hexadecimal string to reach `NODE_NYBBLES_LENGTH`
46033
88e741bf2d93 rust: use NodePrefix::from_hex instead of hex::decode directly
Simon Sapin <simon-commits@exyr.org>
parents: 45531
diff changeset
   285
    ///check_hash
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   286
    /// 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
   287
    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
   288
        let mut res = hex.to_string();
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   289
        while res.len() < NODE_NYBBLES_LENGTH {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   290
            res.push('0');
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
        res
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   293
    }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   294
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   295
    fn sample_node_hex() -> String {
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   296
        hex_pad_right("0123456789abcdeffedcba9876543210deadbeef")
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   297
    }
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   298
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   299
    #[test]
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   300
    fn test_node_from_hex() {
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   301
        assert_eq!(Node::from_hex(&sample_node_hex()).unwrap(), sample_node());
44143
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
        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
   304
        short.pop();
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   305
        short.pop();
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   306
        assert!(Node::from_hex(&short).is_err());
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   307
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   308
        let not_hex = hex_pad_right("012... oops");
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   309
        assert!(Node::from_hex(&not_hex).is_err(),);
44143
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
    #[test]
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   313
    fn test_node_encode_hex() {
46427
6380efb82191 rust: replace Node::encode_hex with std::fmt::LowerHex
Simon Sapin <simon.sapin@octobus.net>
parents: 46391
diff changeset
   314
        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
   315
    }
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   316
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   317
    #[test]
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   318
    fn test_prefix_from_hex() -> Result<(), FromHexError> {
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   319
        assert_eq!(
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   320
            NodePrefix::from_hex("0e1")?,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   321
            NodePrefix {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   322
                buf: vec![14, 16],
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   323
                is_odd: true
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   324
            }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   325
        );
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   326
        assert_eq!(
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   327
            NodePrefix::from_hex("0e1a")?,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   328
            NodePrefix {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   329
                buf: vec![14, 26],
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   330
                is_odd: false
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   331
            }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   332
        );
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   333
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   334
        // checking limit case
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   335
        let node_as_vec = sample_node().data.iter().cloned().collect();
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   336
        assert_eq!(
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   337
            NodePrefix::from_hex(sample_node_hex())?,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   338
            NodePrefix {
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   339
                buf: node_as_vec,
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   340
                is_odd: false
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   341
            }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   342
        );
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   343
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   344
        Ok(())
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   345
    }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   346
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   347
    #[test]
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   348
    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
   349
        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
   350
        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
   351
        long.push('c');
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   352
        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
   353
    }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   354
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   355
    #[test]
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   356
    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
   357
        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
   358
        node_data[0] = 0x12;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   359
        node_data[1] = 0xca;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   360
        let node = Node::from(node_data);
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   361
        assert!(NodePrefix::from_hex("12")?.borrow().is_prefix_of(&node));
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   362
        assert!(!NodePrefix::from_hex("1a")?.borrow().is_prefix_of(&node));
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   363
        assert!(NodePrefix::from_hex("12c")?.borrow().is_prefix_of(&node));
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   364
        assert!(!NodePrefix::from_hex("12d")?.borrow().is_prefix_of(&node));
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   365
        Ok(())
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   366
    }
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   367
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   368
    #[test]
46428
5893706af3de rust: Simplify error type for reading hex node IDs
Simon Sapin <simon.sapin@octobus.net>
parents: 46427
diff changeset
   369
    fn test_get_nybble() -> Result<(), FromHexError> {
44182
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   370
        let prefix = NodePrefix::from_hex("dead6789cafe")?;
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   371
        assert_eq!(prefix.borrow().get_nybble(0), 13);
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   372
        assert_eq!(prefix.borrow().get_nybble(7), 9);
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   373
        Ok(())
9896a8d0d3d2 rust-node: handling binary Node prefix
Georges Racinet <georges.racinet@octobus.net>
parents: 44143
diff changeset
   374
    }
44388
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   375
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   376
    #[test]
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   377
    fn test_first_different_nybble_even_prefix() {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   378
        let prefix = NodePrefix::from_hex("12ca").unwrap();
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   379
        let prefref = prefix.borrow();
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   380
        let mut node = Node::from([0; NODE_BYTES_LENGTH]);
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   381
        assert_eq!(prefref.first_different_nybble(&node), Some(0));
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   382
        node.data[0] = 0x13;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   383
        assert_eq!(prefref.first_different_nybble(&node), Some(1));
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   384
        node.data[0] = 0x12;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   385
        assert_eq!(prefref.first_different_nybble(&node), Some(2));
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   386
        node.data[1] = 0xca;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   387
        // now it is a prefix
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   388
        assert_eq!(prefref.first_different_nybble(&node), None);
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   389
    }
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   390
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   391
    #[test]
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   392
    fn test_first_different_nybble_odd_prefix() {
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   393
        let prefix = NodePrefix::from_hex("12c").unwrap();
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   394
        let prefref = prefix.borrow();
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   395
        let mut node = Node::from([0; NODE_BYTES_LENGTH]);
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   396
        assert_eq!(prefref.first_different_nybble(&node), Some(0));
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   397
        node.data[0] = 0x13;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   398
        assert_eq!(prefref.first_different_nybble(&node), Some(1));
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   399
        node.data[0] = 0x12;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   400
        assert_eq!(prefref.first_different_nybble(&node), Some(2));
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   401
        node.data[1] = 0xca;
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   402
        // now it is a prefix
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   403
        assert_eq!(prefref.first_different_nybble(&node), None);
5ac1eecc9c64 rust-nodemap: core implementation for shortest
Georges Racinet <georges.racinet@octobus.net>
parents: 44187
diff changeset
   404
    }
44143
7f86426fdd2c rust-node: binary Node ID and conversion utilities
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   405
}
44183
e52401a95b94 rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents: 44182
diff changeset
   406
e52401a95b94 rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents: 44182
diff changeset
   407
#[cfg(test)]
e52401a95b94 rust-nodemap: NodeMap trait with simplest implementation
Georges Racinet <georges.racinet@octobus.net>
parents: 44182
diff changeset
   408
pub use tests::hex_pad_right;