Mercurial > public > mercurial-scm > hg
diff rust/hg-pyo3/src/node.rs @ 52785:71ebe880f24a
hg-pyo3-revlog: Node conversion utilities
Adapted from `rusthg::utils`. The `NodeData` intermediate type was
no longer necessary, as the core `Node` now implements `TryFrom`.
Leaving the original unchanged, as we intend to drop it at the end
of the story.
author | Georges Racinet <georges.racinet@cloudcrane.io> |
---|---|
date | Wed, 25 Dec 2024 11:58:56 +0100 |
parents | |
children | 4e34e8fd46d4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hg-pyo3/src/node.rs Wed Dec 25 11:58:56 2024 +0100 @@ -0,0 +1,58 @@ +#![allow(dead_code)] +use pyo3::exceptions::PyValueError; +use pyo3::prelude::*; +use pyo3::types::PyBytes; + +use hg::revlog::RevlogIndex; +use hg::{ + revlog::index::Index, revlog::node::NODE_BYTES_LENGTH, Node, NodePrefix, + Revision, +}; + +#[derive(Debug, Copy, Clone, PartialEq, derive_more::From)] +pub struct PyNode(Node); + +/// Copy incoming Python binary Node ID into [`Node`] +/// +/// # Python exceptions +/// Raises `ValueError` if length is not as expected +pub fn node_from_py_bytes(bytes: &Bound<'_, PyBytes>) -> PyResult<Node> { + Node::try_from(bytes.as_bytes()).map_err(|_| { + PyValueError::new_err(format!( + "{}-byte hash required", + NODE_BYTES_LENGTH + )) + }) +} + +/// Convert Python hexadecimal Node ID node or prefix given as `bytes` into +/// [`NodePrefix`]. +/// +/// # Python exceptions +/// Raises `ValueError` if the incoming `bytes` is invalid. +pub fn node_prefix_from_py_bytes( + bytes: &Bound<'_, PyBytes>, +) -> PyResult<NodePrefix> { + let as_bytes = bytes.as_bytes(); + NodePrefix::from_hex(as_bytes).map_err(|_| { + PyValueError::new_err(format!( + "Invalid node or prefix '{}'", + String::from_utf8_lossy(as_bytes) + )) + }) +} + +/// Return the binary node from a checked revision +/// +/// This is meant to be used on revisions already checked to exist, +/// typically obtained from a NodeTree lookup. +/// +/// # Panics +/// Panics if the revision does not exist +pub fn py_node_for_rev<'py>( + py: Python<'py>, + idx: &Index, + rev: Revision, +) -> Bound<'py, PyBytes> { + PyBytes::new(py, idx.node(rev).expect("node should exist").as_bytes()) +}