Mercurial > hg
view rust/hg-cpython/src/dirstate/dirs_multiset.rs @ 52304:04b9a56c2d25
rust-lib: only export very common types to the top of the crate
This was done very early in the Rust project's lifecycle and I had very little
Rust experience. Let's keep the `DirstateParents` since they'll pop up in
all higher-level code and make the rest more explicit imports to make the
imports less confusing and the lib less cluttered.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Mon, 04 Nov 2024 11:13:05 +0100 |
parents | 6a019a037085 |
children |
line wrap: on
line source
// dirs_multiset.rs // // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> // // This software may be used and distributed according to the terms of the // GNU General Public License version 2 or any later version. //! Bindings for the `hg::dirstate::dirs_multiset` file provided by the //! `hg-core` package. use std::cell::RefCell; use cpython::{ exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult, Python, UnsafePyLeaked, }; use hg::{ dirstate::dirs_multiset::{DirsMultiset, DirsMultisetIter}, utils::hg_path::{HgPath, HgPathBuf}, }; py_class!(pub class Dirs |py| { @shared data inner: DirsMultiset; // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes // a `list`) def __new__( _cls, map: PyObject, ) -> PyResult<Self> { let inner = if map.cast_as::<PyDict>(py).is_ok() { let err = "pathutil.dirs() with a dict should only be used by the Python dirstatemap \ and should not be used when Rust is enabled"; return Err(PyErr::new::<exc::TypeError, _>(py, err.to_string())) } else { let map: Result<Vec<HgPathBuf>, PyErr> = map .iter(py)? .map(|o| { Ok(HgPathBuf::from_bytes( o?.extract::<PyBytes>(py)?.data(py), )) }) .collect(); DirsMultiset::from_manifest(&map?) .map_err(|e| { PyErr::new::<exc::ValueError, _>(py, e.to_string()) })? }; Self::create_instance(py, inner) } def addpath(&self, path: PyObject) -> PyResult<PyObject> { self.inner(py).borrow_mut().add_path( HgPath::new(path.extract::<PyBytes>(py)?.data(py)), ).and(Ok(py.None())).map_err(|e| PyErr::new::<exc::ValueError, _>( py, e.to_string(), ) ) } def delpath(&self, path: PyObject) -> PyResult<PyObject> { self.inner(py).borrow_mut().delete_path( HgPath::new(path.extract::<PyBytes>(py)?.data(py)), ) .and(Ok(py.None())) .map_err(|e| PyErr::new::<exc::ValueError, _>( py, e.to_string(), ) ) } def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> { let leaked_ref = self.inner(py).leak_immutable(); DirsMultisetKeysIterator::from_inner( py, unsafe { leaked_ref.map(py, |o| o.iter()) }, ) } def __contains__(&self, item: PyObject) -> PyResult<bool> { Ok(self.inner(py).borrow().contains(HgPath::new( item.extract::<PyBytes>(py)?.data(py), ))) } }); impl Dirs { pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> { Self::create_instance(py, d) } fn translate_key( py: Python, res: &HgPathBuf, ) -> PyResult<Option<PyBytes>> { Ok(Some(PyBytes::new(py, res.as_bytes()))) } } py_shared_iterator!( DirsMultisetKeysIterator, UnsafePyLeaked<DirsMultisetIter<'static>>, Dirs::translate_key, Option<PyBytes> );