Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-cpython/src/ancestors.rs @ 41117:b31a41f24864
rust-cpython: binding for LazyAncestors
The `mercurial.rustext.ancestor` module will not in the foreseeable
future be a drop-in replacement for the pure `mercurial.ancestor`, because the
Rust variants take the index at instantiation whereas the Python ones
take a parents function. From the Python side, using the index from `ancestor`
would leak internal details out of `mercurial.revlog`, and that's unwanted.
Therefore, given that classes defined in
`rust-cpython` have the same names in both language, we keep the Rust naming
convention (CamelCase).
Eventually, though, the ancestor module can be placed under control of
`mercurial.policy`, but it will still be up to `revlog` to be aware of
that and play the role of a factory for instantiation.
Differential Revision: https://phab.mercurial-scm.org/D5441
author | Georges Racinet <gracinet@anybox.fr> |
---|---|
date | Thu, 13 Dec 2018 18:53:40 +0100 |
parents | d9f439fcdb4c |
children | dcf818267bc1 |
line wrap: on
line diff
--- a/rust/hg-cpython/src/ancestors.rs Fri Dec 28 03:28:02 2018 +0100 +++ b/rust/hg-cpython/src/ancestors.rs Thu Dec 13 18:53:40 2018 +0100 @@ -13,8 +13,8 @@ }; use exceptions::GraphError; use hg; -use hg::AncestorsIterator as CoreIterator; use hg::Revision; +use hg::{AncestorsIterator as CoreIterator, LazyAncestors as CoreLazy}; use std::cell::RefCell; /// Utility function to convert a Python iterable into a Vec<Revision> @@ -70,6 +70,37 @@ } } +py_class!(class LazyAncestors |py| { + data inner: RefCell<Box<CoreLazy<Index>>>; + + def __contains__(&self, rev: Revision) -> PyResult<bool> { + self.inner(py) + .borrow_mut() + .contains(rev) + .map_err(|e| GraphError::pynew(py, e)) + } + + def __iter__(&self) -> PyResult<AncestorsIterator> { + AncestorsIterator::from_inner(py, self.inner(py).borrow().iter()) + } + + def __bool__(&self) -> PyResult<bool> { + Ok(!self.inner(py).borrow().is_empty()) + } + + def __new__(_cls, index: PyObject, initrevs: PyObject, stoprev: Revision, + inclusive: bool) -> PyResult<Self> { + let initvec = reviter_to_revvec(py, initrevs)?; + + let lazy = + CoreLazy::new(Index::new(py, index)?, initvec, stoprev, inclusive) + .map_err(|e| GraphError::pynew(py, e))?; + + Self::create_instance(py, RefCell::new(Box::new(lazy))) + } + +}); + /// Create the module, with __package__ given from parent pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { let dotted_name = &format!("{}.ancestor", package); @@ -81,6 +112,7 @@ "Generic DAG ancestor algorithms - Rust implementation", )?; m.add_class::<AncestorsIterator>(py)?; + m.add_class::<LazyAncestors>(py)?; let sys = PyModule::import(py, "sys")?; let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;