Mercurial > public > mercurial-scm > hg-stable
changeset 52870:c60f69556924
rust-pyo3: new module for conversions of HgPath and friends
Same as `PyRevision`, the `PyHgPathRef` new-type wrapper is not
a Python type, but it implements `IntoPyObject`, which will spare
us tedious uses of `PyBytes::new`.
The `paths_py_list` function is the the analog of `revs_py_list`
for paths. There was one similar utility in `hg-cpython`, within
the `dirstate::status` module. We feel it should be in a more global
location, and have a name consistent with utilities for revisions.
The `paths_pyiter_collect` function is similarly the analog of
`revs_pyiter_collect`.
author | Georges Racinet <georges.racinet@cloudcrane.io> |
---|---|
date | Thu, 06 Feb 2025 11:18:28 +0100 |
parents | e7b825893e1b |
children | 9f083ff3c96c |
files | rust/hg-pyo3/src/lib.rs rust/hg-pyo3/src/path.rs |
diffstat | 2 files changed, 68 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-pyo3/src/lib.rs Wed Jan 29 14:05:26 2025 +0100 +++ b/rust/hg-pyo3/src/lib.rs Thu Feb 06 11:18:28 2025 +0100 @@ -6,6 +6,7 @@ mod discovery; mod exceptions; mod node; +mod path; mod revision; mod revlog; mod store;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/hg-pyo3/src/path.rs Thu Feb 06 11:18:28 2025 +0100 @@ -0,0 +1,67 @@ +// path.rs +// +// Copyright 2019 Raphaël Gomès <rgomes@octobus.net> +// 2025 Georges Racinet <georges.racinet@cloudcrane.io> +// +// This software may be used and distributed according to the terms of the +// GNU General Public License version 2 or any later version. +//! Utilities about `HgPath` and related objects provided by the `hg-core` +//! package. + +use pyo3::prelude::*; +use pyo3::types::{PyBytes, PyList}; + +use std::convert::Infallible; + +use hg::utils::hg_path::{HgPath, HgPathBuf}; + +#[allow(dead_code)] +#[derive(Eq, Ord, PartialEq, PartialOrd, Hash, derive_more::From)] +pub struct PyHgPathRef<'a>(pub &'a HgPath); + +impl<'py> IntoPyObject<'py> for PyHgPathRef<'_> { + type Target = PyBytes; + type Output = Bound<'py, Self::Target>; + type Error = Infallible; + + fn into_pyobject( + self, + py: Python<'py>, + ) -> Result<Self::Output, Self::Error> { + Ok(PyBytes::new(py, self.0.as_bytes())) + } +} + +#[allow(dead_code)] +pub fn paths_py_list<I, U>( + py: Python<'_>, + paths: impl IntoIterator<Item = I, IntoIter = U>, +) -> PyResult<Py<PyList>> +where + I: AsRef<HgPath>, + U: ExactSizeIterator<Item = I>, +{ + Ok(PyList::new( + py, + paths + .into_iter() + .map(|p| PyBytes::new(py, p.as_ref().as_bytes())), + )? + .unbind()) +} + +#[allow(dead_code)] +pub fn paths_pyiter_collect<C>(paths: &Bound<'_, PyAny>) -> PyResult<C> +where + C: FromIterator<HgPathBuf>, +{ + paths + .try_iter()? + .map(|p| { + let path = p?; + Ok(HgPathBuf::from_bytes( + path.downcast::<PyBytes>()?.as_bytes(), + )) + }) + .collect() +}