Mercurial > hg
changeset 44505:d738b7a18438
rust-nodemap: add utils to create `Node`s from Python objects
Differential Revision: https://phab.mercurial-scm.org/D8155
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Tue, 11 Feb 2020 16:25:45 +0100 |
parents | cefd130c98be |
children | 26dd35ac59b8 |
files | rust/hg-cpython/src/utils.rs |
diffstat | 1 files changed, 35 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-cpython/src/utils.rs Tue Feb 11 16:23:06 2020 +0100 +++ b/rust/hg-cpython/src/utils.rs Tue Feb 11 16:25:45 2020 +0100 @@ -1,4 +1,7 @@ -use cpython::{PyDict, PyObject, PyResult, PyTuple, Python}; +use cpython::exc::ValueError; +use cpython::{PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple, Python}; +use hg::revlog::Node; +use std::convert::TryFrom; #[allow(unused)] pub fn print_python_trace(py: Python) -> PyResult<PyObject> { @@ -11,3 +14,34 @@ kwargs.set_item(py, "file", sys.get(py, "stderr")?)?; traceback.call(py, "print_stack", PyTuple::new(py, &[]), Some(&kwargs)) } + +// Necessary evil for the time being, could maybe be moved to +// a TryFrom in Node itself +const NODE_BYTES_LENGTH: usize = 20; +type NodeData = [u8; NODE_BYTES_LENGTH]; + +/// Copy incoming Python bytes given as `PyObject` into `Node`, +/// doing the necessary checks +pub fn node_from_py_object<'a>( + py: Python, + bytes: &'a PyObject, +) -> PyResult<Node> { + let as_py_bytes: &'a PyBytes = bytes.extract(py)?; + node_from_py_bytes(py, as_py_bytes) +} + +/// Clone incoming Python bytes given as `PyBytes` as a `Node`, +/// doing the necessary checks. +pub fn node_from_py_bytes<'a>( + py: Python, + bytes: &'a PyBytes, +) -> PyResult<Node> { + <NodeData>::try_from(bytes.data(py)) + .map_err(|_| { + PyErr::new::<ValueError, _>( + py, + format!("{}-byte hash required", NODE_BYTES_LENGTH), + ) + }) + .map(|n| n.into()) +}