##// END OF EJS Templates
rust-cpython: remove Option<_> from interface of py_shared_iterator...
rust-cpython: remove Option<_> from interface of py_shared_iterator It's the implementation detail of the py_shared_iterator that the leaked reference is kept in Option<_> so that it can be dropped early.

File last commit:

r43159:ea91a126 default
r43160:74d67c64 default
Show More
dirs_multiset.rs
130 lines | 3.9 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 // 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;
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 use std::convert::TryInto;
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991
use cpython::{
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult,
Python,
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 };
Yuya Nishihara
rust-cpython: introduce restricted variant of RefCell...
r43115 use crate::dirstate::extract_dirstate;
use crate::ref_sharing::{PySharedRefCell, PySharedState};
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of sequence with concrete type...
r43157 use hg::{
DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError,
EntryState,
};
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991
py_class!(pub class Dirs |py| {
Yuya Nishihara
rust-cpython: introduce restricted variant of RefCell...
r43115 data inner: PySharedRefCell<DirsMultiset>;
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 data py_shared_state: PySharedState;
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991
// `map` is either a `dict` or a flat iterator (usually a `set`, sometimes
// a `list`)
def __new__(
_cls,
map: PyObject,
skip: Option<PyObject> = None
) -> PyResult<Self> {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 let mut skip_state: Option<EntryState> = None;
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 if let Some(skip) = skip {
Raphaël Gomès
rust-dirstate: use EntryState enum instead of literals...
r42994 skip_state = Some(
skip.extract::<PyBytes>(py)?.data(py)[0]
.try_into()
.map_err(|e: DirstateParseError| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
})?,
);
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 }
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 let inner = if let Ok(map) = map.cast_as::<PyDict>(py) {
let dirstate = extract_dirstate(py, &map)?;
Yuya Nishihara
rust-dirstate: split DirsMultiset constructor per input type...
r43070 DirsMultiset::from_dirstate(&dirstate, skip_state)
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 } else {
let map: Result<Vec<Vec<u8>>, PyErr> = map
.iter(py)?
.map(|o| Ok(o?.extract::<PyBytes>(py)?.data(py).to_owned()))
.collect();
Yuya Nishihara
rust-dirstate: split DirsMultiset constructor per input type...
r43070 DirsMultiset::from_manifest(&map?)
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 };
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 Self::create_instance(
py,
Yuya Nishihara
rust-cpython: introduce restricted variant of RefCell...
r43115 PySharedRefCell::new(inner),
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 PySharedState::default()
)
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 }
def addpath(&self, path: PyObject) -> PyResult<PyObject> {
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 self.borrow_mut(py)?.add_path(
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 path.extract::<PyBytes>(py)?.data(py),
);
Ok(py.None())
}
def delpath(&self, path: PyObject) -> PyResult<PyObject> {
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 self.borrow_mut(py)?.delete_path(
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 path.extract::<PyBytes>(py)?.data(py),
)
.and(Ok(py.None()))
.or_else(|e| {
match e {
DirstateMapError::PathNotFound(_p) => {
Err(PyErr::new::<exc::ValueError, _>(
py,
"expected a value, found none".to_string(),
))
}
DirstateMapError::EmptyPath => {
Ok(py.None())
}
}
})
}
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> {
Yuya Nishihara
rust-cpython: mark unsafe functions as such...
r43117 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 DirsMultisetKeysIterator::create_instance(
py,
Yuya Nishihara
rust-cpython: pair leaked reference with its manager object...
r43116 RefCell::new(Some(leak_handle)),
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of sequence with concrete type...
r43157 RefCell::new(leaked_ref.iter()),
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 )
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 }
def __contains__(&self, item: PyObject) -> PyResult<bool> {
Ok(self
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 .inner(py)
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 .borrow()
Raphaël Gomès
rust-dirstate: improve API of `DirsMultiset`...
r42995 .contains(item.extract::<PyBytes>(py)?.data(py).as_ref()))
Raphaël Gomès
rust-dirstate: create dirstate submodule in hg-cpython...
r42991 }
});
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997
py_shared_ref!(Dirs, DirsMultiset, inner, DirsMultisetLeakedRef,);
impl Dirs {
pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> {
Yuya Nishihara
rust-cpython: introduce restricted variant of RefCell...
r43115 Self::create_instance(
py,
PySharedRefCell::new(d),
PySharedState::default(),
)
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 }
fn translate_key(py: Python, res: &Vec<u8>) -> PyResult<Option<PyBytes>> {
Ok(Some(PyBytes::new(py, res)))
}
}
Yuya Nishihara
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator...
r43159 py_shared_iterator!(
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 DirsMultisetKeysIterator,
DirsMultisetLeakedRef,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of sequence with concrete type...
r43157 DirsMultisetIter<'static>,
Raphaël Gomès
rust-cpython: add macro for sharing references...
r42997 Dirs::translate_key,
Option<PyBytes>
);