--- 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())
+}