rust/hg-pyo3/src/node.rs
author Georges Racinet <georges.racinet@cloudcrane.io>
Wed, 25 Dec 2024 16:16:22 +0100
changeset 52786 4e34e8fd46d4
parent 52785 71ebe880f24a
child 52856 e2d2961b8383
permissions -rw-r--r--
rust-pyo3-revlog: nodemap based index methods They are rather straightforward, except for `_index_get_rev` that takes care of not initializing a nodetree on some conditions. In `_index_partialmatch`, we solve the todo that was in the `hg-cpython`, since we introduced the `py_node_for_rev` helper earlier. The new test method in `test-rust-revlog.py` provides comparison with the `hg-cpython` implementation of `InnerRevlog`.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52785
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     1
use pyo3::exceptions::PyValueError;
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     2
use pyo3::prelude::*;
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     3
use pyo3::types::PyBytes;
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     4
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     5
use hg::revlog::RevlogIndex;
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     6
use hg::{
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     7
    revlog::index::Index, revlog::node::NODE_BYTES_LENGTH, Node, NodePrefix,
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     8
    Revision,
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
     9
};
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    10
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    11
#[derive(Debug, Copy, Clone, PartialEq, derive_more::From)]
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    12
pub struct PyNode(Node);
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    13
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    14
/// Copy incoming Python binary Node ID into [`Node`]
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    15
///
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    16
/// # Python exceptions
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    17
/// Raises `ValueError` if length is not as expected
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    18
pub fn node_from_py_bytes(bytes: &Bound<'_, PyBytes>) -> PyResult<Node> {
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    19
    Node::try_from(bytes.as_bytes()).map_err(|_| {
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    20
        PyValueError::new_err(format!(
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    21
            "{}-byte hash required",
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    22
            NODE_BYTES_LENGTH
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    23
        ))
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    24
    })
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    25
}
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    26
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    27
/// Convert Python hexadecimal Node ID node or prefix given as `bytes` into
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    28
/// [`NodePrefix`].
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    29
///
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    30
/// # Python exceptions
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    31
/// Raises `ValueError` if the incoming `bytes` is invalid.
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    32
pub fn node_prefix_from_py_bytes(
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    33
    bytes: &Bound<'_, PyBytes>,
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    34
) -> PyResult<NodePrefix> {
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    35
    let as_bytes = bytes.as_bytes();
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    36
    NodePrefix::from_hex(as_bytes).map_err(|_| {
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    37
        PyValueError::new_err(format!(
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    38
            "Invalid node or prefix '{}'",
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    39
            String::from_utf8_lossy(as_bytes)
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    40
        ))
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    41
    })
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    42
}
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    43
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    44
/// Return the binary node from a checked revision
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    45
///
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    46
/// This is meant to be used on revisions already checked to exist,
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    47
/// typically obtained from a NodeTree lookup.
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    48
///
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    49
/// # Panics
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    50
/// Panics if the revision does not exist
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    51
pub fn py_node_for_rev<'py>(
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    52
    py: Python<'py>,
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    53
    idx: &Index,
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    54
    rev: Revision,
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    55
) -> Bound<'py, PyBytes> {
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    56
    PyBytes::new(py, idx.node(rev).expect("node should exist").as_bytes())
71ebe880f24a hg-pyo3-revlog: Node conversion utilities
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff changeset
    57
}