annotate rust/hg-cpython/src/ancestors.rs @ 51260:7eea2e4109ae

rust-index: using the `hg::index::Index` in ancestors iterator and lazy set Since there is no Rust implementation for REVLOGV2/CHANGELOGv2, we declare them to be incompatible with Rust, hence indexes in these formats will use the implementations from Python `mercurial.ancestor`. If this is an unacceptable performance hit for current users of these formats, we can later on add Rust implementations based on the C index for them or implement these formats for the Rust indexes. Among the challenges that we had to meet, we wanted to avoid taking the GIL each time the inner (vcsgraph) iterator has to call the parents function. This would probably still be acceptable in terms of performance with `AncestorsIterator`, but not with `LazyAncestors` nor for the upcoming change in `MissingAncestors`. Hence we enclose the reference to the index in a `PySharedRef`, leading to more rigourous checking of mutations, which does pass now that there no logically immutable methods of `hg::index::Index` that take a mutable reference as input.
author Georges Racinet <georges.racinet@octobus.net>
date Fri, 27 Oct 2023 22:11:05 +0200
parents 4c5f6e95df84
children 59d81768ad6d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40978
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
1 // ancestors.rs
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
2 //
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
4 //
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
5 // This software may be used and distributed according to the terms of the
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
6 // GNU General Public License version 2 or any later version.
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
7
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
8 //! Bindings for the `hg::ancestors` module provided by the
40978
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
9 //! `hg-core` crate. From Python, this will be seen as `rustext.ancestor`
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
10 //! and can be used as replacement for the the pure `ancestor` Python module.
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
11 //!
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
12 //! # Classes visible from Python:
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
13 //! - [`LazyAncestors`] is the Rust implementation of
41243
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
14 //! `mercurial.ancestor.lazyancestors`. The only difference is that it is
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
15 //! instantiated with a C `parsers.index` instance instead of a parents
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
16 //! function.
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
17 //!
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
18 //! - [`MissingAncestors`] is the Rust implementation of
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
19 //! `mercurial.ancestor.incrementalmissingancestors`.
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
20 //!
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
21 //! API differences:
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
22 //! + it is instantiated with a C `parsers.index`
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
23 //! instance instead of a parents function.
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
24 //! + `MissingAncestors.bases` is a method returning a tuple instead of
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
25 //! a set-valued attribute. We could return a Python set easily if our
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
26 //! [PySet PR](https://github.com/dgrunwald/rust-cpython/pull/165)
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
27 //! is accepted.
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
28 //!
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
29 //! - [`AncestorsIterator`] is the Rust counterpart of the
41243
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
30 //! `ancestor._lazyancestorsiter` Python generator. From Python, instances of
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
31 //! this should be mainly obtained by calling `iter()` on a [`LazyAncestors`]
5257e6299d4c rust-cpython: set conversion for MissingAncestors.bases()
Georges Racinet <georges.racinet@octobus.net>
parents: 41240
diff changeset
32 //! instance.
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
33 //!
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
34 //! [`LazyAncestors`]: struct.LazyAncestors.html
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
35 //! [`MissingAncestors`]: struct.MissingAncestors.html
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
36 //! [`AncestorsIterator`]: struct.AncestorsIterator.html
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
37 use crate::revlog::{py_rust_index_to_graph, pyindex_to_graph};
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
38 use crate::PyRevision;
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 41704
diff changeset
39 use crate::{
43269
33fe96a5c522 rust-cpython: removed now useless py_set() conversion
Georges Racinet <georges.racinet@octobus.net>
parents: 42609
diff changeset
40 cindex::Index, conversion::rev_pyiter_collect, exceptions::GraphError,
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
41 revlog::PySharedIndex,
42609
326fdce22fb2 rust: switch hg-core and hg-cpython to rust 2018 edition
Raphaël Gomès <rgomes@octobus.net>
parents: 41704
diff changeset
42 };
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
43 use cpython::{
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
44 ObjectProtocol, PyClone, PyDict, PyErr, PyList, PyModule, PyObject,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
45 PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked,
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
46 };
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
47
48556
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
48 use hg::MissingAncestors as CoreMissing;
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
49 use hg::Revision;
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
50 use std::cell::RefCell;
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
51 use std::collections::HashSet;
48556
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
52 use vcsgraph::lazy_ancestors::{
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
53 AncestorsIterator as VCGAncestorsIterator,
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
54 LazyAncestors as VCGLazyAncestors,
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
55 };
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
56
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
57 // Error propagation for an [`UnsafePyLeaked`] wrapping a [`Result`]
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
58 //
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
59 // It would be nice for UnsharedPyLeaked to provide this directly as a variant
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
60 // of the `map` method with a signature such as:
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
61 //
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
62 // ```
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
63 // unafe fn map_or_err(py: Python,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
64 // f: impl FnOnce(T) -> Result(U, E),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
65 // convert_err: impl FnOnce(Python, E) -> PyErr)
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
66 // ```
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
67 //
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
68 // This would spare users of the `cpython` crate the additional `unsafe` deref
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
69 // to inspect the error and return it outside `UnsafePyLeaked`, and the
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
70 // subsequent unwrapping that this function performs.
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
71 fn pyleaked_or_map_err<T, E: std::fmt::Debug + Copy>(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
72 py: Python,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
73 leaked: UnsafePyLeaked<Result<T, E>>,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
74 convert_err: impl FnOnce(Python, E) -> PyErr,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
75 ) -> PyResult<UnsafePyLeaked<T>> {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
76 // Result.inspect_err is unstable in Rust 1.61
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
77 if let Err(e) = *unsafe { leaked.try_borrow(py)? } {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
78 return Err(convert_err(py, e));
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
79 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
80 Ok(unsafe {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
81 leaked.map(py, |res| {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
82 res.expect("Error case should have already be treated")
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
83 })
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
84 })
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
85 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
86
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
87 py_class!(pub class AncestorsIterator |py| {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
88 data inner: RefCell<UnsafePyLeaked<VCGAncestorsIterator<PySharedIndex>>>;
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
89
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
90 def __next__(&self) -> PyResult<Option<PyRevision>> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
91 let mut leaked = self.inner(py).borrow_mut();
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
92 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
93 match inner.next() {
48556
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
94 Some(Err(e)) => Err(GraphError::pynew_from_vcsgraph(py, e)),
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
95 None => Ok(None),
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
96 Some(Ok(r)) => Ok(Some(PyRevision(r))),
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
97 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
98 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
99
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
100 def __contains__(&self, rev: PyRevision) -> PyResult<bool> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
101 let mut leaked = self.inner(py).borrow_mut();
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
102 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
103 inner.contains(rev.0)
48556
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
104 .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
105 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
106
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
107 def __iter__(&self) -> PyResult<Self> {
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
108 Ok(self.clone_ref(py))
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
109 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
110
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
111 def __new__(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
112 _cls,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
113 index: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
114 initrevs: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
115 stoprev: PyRevision,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
116 inclusive: bool
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
117 ) -> PyResult<AncestorsIterator> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
118 Self::inner_new(py, index, initrevs, stoprev, inclusive)
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
119 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
120
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
121 });
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
122
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
123 impl AncestorsIterator {
48556
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
124 pub fn from_inner(
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
125 py: Python,
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
126 ait: UnsafePyLeaked<VCGAncestorsIterator<PySharedIndex>>,
48556
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
127 ) -> PyResult<Self> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
128 Self::create_instance(py, RefCell::new(ait))
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
129 }
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
130
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
131 pub fn inner_new(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
132 py: Python,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
133 index: PyObject,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
134 initrevs: PyObject,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
135 stoprev: PyRevision,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
136 inclusive: bool,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
137 ) -> PyResult<AncestorsIterator> {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
138 let index = py_rust_index_to_graph(py, index)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
139 let initvec: Vec<_> = {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
140 let borrowed_idx = unsafe { index.try_borrow(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
141 rev_pyiter_collect(py, &initrevs, &*borrowed_idx)?
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
142 };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
143 let res_ait = unsafe {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
144 index.map(py, |idx| {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
145 VCGAncestorsIterator::new(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
146 idx,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
147 initvec.into_iter().map(|r| r.0),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
148 stoprev.0,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
149 inclusive,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
150 )
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
151 })
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
152 };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
153 let ait =
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
154 pyleaked_or_map_err(py, res_ait, GraphError::pynew_from_vcsgraph)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
155 AncestorsIterator::from_inner(py, ait)
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
156 }
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
157 }
40978
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
158
41184
dcf818267bc1 rust-cpython: rustdoc improvements
Georges Racinet <georges.racinet@octobus.net>
parents: 41117
diff changeset
159 py_class!(pub class LazyAncestors |py| {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
160 data inner: RefCell<UnsafePyLeaked<
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
161 RefCell<VCGLazyAncestors<PySharedIndex>>
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
162 >>;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
163 data index: PyObject;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
164 data initrevs: PyObject;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
165 data stoprev: PyRevision;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
166 data inclusive: bool;
41117
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
167
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
168 def __contains__(&self, rev: PyRevision) -> PyResult<bool> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
169 let leaked = self.inner(py).borrow();
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
170 let inner: &RefCell<VCGLazyAncestors<PySharedIndex>> =
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
171 &*unsafe { leaked.try_borrow(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
172 let inner_mut: &mut VCGLazyAncestors<PySharedIndex> =
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
173 &mut *inner.borrow_mut();
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
174 inner_mut.contains(rev.0)
48556
35ebe6f824be hg-cpython: use ancestor iterator impls from vcsgraph
pacien <pacien.trangirard@pacien.net>
parents: 44199
diff changeset
175 .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
41117
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
176 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
177
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
178 def __iter__(&self) -> PyResult<AncestorsIterator> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
179 let index = self.index(py).clone_ref(py);
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
180 let initrevs = self.initrevs(py).clone_ref(py);
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
181 AncestorsIterator::inner_new(py, index, initrevs,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
182 *self.stoprev(py),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
183 *self.inclusive(py))
41117
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
184 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
185
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
186 def __bool__(&self) -> PyResult<bool> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
187 let leaked = self.inner(py).borrow();
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
188 let inner = unsafe { leaked.try_borrow(py)? };
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
189 let empty = inner.borrow().is_empty();
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
190 Ok(!empty)
41117
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
191 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
192
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
193 def __new__(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
194 _cls,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
195 index: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
196 initrevs: PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
197 stoprev: PyRevision,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
198 inclusive: bool
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
199 ) -> PyResult<Self> {
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
200 let cloned_index = index.clone_ref(py);
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
201 let index = py_rust_index_to_graph(py, index)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
202 let initvec: Vec<_> = {
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
203 let borrowed_idx = unsafe {index.try_borrow(py)?};
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
204 rev_pyiter_collect(py, &initrevs, &*borrowed_idx)?
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
205 };
41117
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
206
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
207 let res_lazy =
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
208 unsafe { index.map(py, |idx| VCGLazyAncestors::new(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
209 idx,
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
210 initvec.into_iter().map(|r| r.0),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
211 stoprev.0,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
212 inclusive
51260
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
213 ))};
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
214 let lazy = pyleaked_or_map_err(py, res_lazy,
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
215 GraphError::pynew_from_vcsgraph)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
216 let lazy_cell = unsafe { lazy.map(py, RefCell::new)};
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
217 let res = Self::create_instance(
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
218 py, RefCell::new(lazy_cell),
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
219 cloned_index, initrevs, stoprev, inclusive)?;
7eea2e4109ae rust-index: using the `hg::index::Index` in ancestors iterator and lazy set
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
220 Ok(res)
41117
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
221 }
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
222
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
223 });
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
224
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
225 py_class!(pub class MissingAncestors |py| {
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
226 data inner: RefCell<Box<CoreMissing<Index>>>;
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
227 data index: RefCell<Index>;
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
228
44199
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43951
diff changeset
229 def __new__(
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43951
diff changeset
230 _cls,
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43951
diff changeset
231 index: PyObject,
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43951
diff changeset
232 bases: PyObject
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43951
diff changeset
233 )
b24721e7c5ee rust-format: cleanup ancestors.rs to make rustfmt happy
Raphaël Gomès <rgomes@octobus.net>
parents: 43951
diff changeset
234 -> PyResult<MissingAncestors> {
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
235 let index = pyindex_to_graph(py, index)?;
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
236 let bases_vec: Vec<_> = rev_pyiter_collect(py, &bases, &index)?;
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
237
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
238 let inner = CoreMissing::new(index.clone_ref(py), bases_vec);
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
239 MissingAncestors::create_instance(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
240 py,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
241 RefCell::new(Box::new(inner)),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
242 RefCell::new(index)
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
243 )
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
244 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
245
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
246 def hasbases(&self) -> PyResult<bool> {
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
247 Ok(self.inner(py).borrow().has_bases())
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
248 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
249
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
250 def addbases(&self, bases: PyObject) -> PyResult<PyObject> {
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
251 let index = self.index(py).borrow();
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
252 let bases_vec: Vec<_> = rev_pyiter_collect(py, &bases, &*index)?;
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
253 let mut inner = self.inner(py).borrow_mut();
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
254 inner.add_bases(bases_vec);
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
255 // cpython doc has examples with PyResult<()> but this gives me
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
256 // the trait `cpython::ToPyObject` is not implemented for `()`
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
257 // so let's return an explicit None
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
258 Ok(py.None())
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
259 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
260
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
261 def bases(&self) -> PyResult<HashSet<PyRevision>> {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
262 Ok(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
263 self.inner(py)
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
264 .borrow()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
265 .get_bases()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
266 .iter()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
267 .map(|r| PyRevision(r.0))
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
268 .collect()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
269 )
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
270 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
271
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
272 def basesheads(&self) -> PyResult<HashSet<PyRevision>> {
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41243
diff changeset
273 let inner = self.inner(py).borrow();
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
274 Ok(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
275 inner
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
276 .bases_heads()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
277 .map_err(|e| GraphError::pynew(py, e))?
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
278 .into_iter()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
279 .map(|r| PyRevision(r.0))
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
280 .collect()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
281 )
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41243
diff changeset
282 }
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41243
diff changeset
283
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
284 def removeancestorsfrom(&self, revs: PyObject) -> PyResult<PyObject> {
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
285 let index = self.index(py).borrow();
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
286 // this is very lame: we convert to a Rust set, update it in place
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
287 // and then convert back to Python, only to have Python remove the
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
288 // excess (thankfully, Python is happy with a list or even an iterator)
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
289 // Leads to improve this:
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
290 // - have the CoreMissing instead do something emit revisions to
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
291 // discard
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
292 // - define a trait for sets of revisions in the core and implement
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
293 // it for a Python set rewrapped with the GIL marker
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
294 let mut revs_pyset: HashSet<Revision> = rev_pyiter_collect(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
295 py, &revs, &*index
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
296 )?;
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
297 let mut inner = self.inner(py).borrow_mut();
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
298 inner.remove_ancestors_from(&mut revs_pyset)
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
299 .map_err(|e| GraphError::pynew(py, e))?;
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
300
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
301 // convert as Python list
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
302 let mut remaining_pyint_vec: Vec<PyObject> = Vec::with_capacity(
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
303 revs_pyset.len());
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
304 for rev in revs_pyset {
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
305 remaining_pyint_vec.push(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
306 PyRevision(rev.0).to_py_object(py).into_object()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
307 );
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
308 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
309 let remaining_pylist = PyList::new(py, remaining_pyint_vec.as_slice());
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
310 revs.call_method(py, "intersection_update", (remaining_pylist, ), None)
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
311 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
312
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
313 def missingancestors(&self, revs: PyObject) -> PyResult<PyList> {
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
314 let index = self.index(py).borrow();
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
315 let revs_vec: Vec<Revision> = rev_pyiter_collect(py, &revs, &*index)?;
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
316
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
317 let mut inner = self.inner(py).borrow_mut();
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
318 let missing_vec = match inner.missing_ancestors(revs_vec) {
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
319 Ok(missing) => missing,
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
320 Err(e) => {
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
321 return Err(GraphError::pynew(py, e));
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
322 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
323 };
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
324 // convert as Python list
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
325 let mut missing_pyint_vec: Vec<PyObject> = Vec::with_capacity(
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
326 missing_vec.len());
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
327 for rev in missing_vec {
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
328 missing_pyint_vec.push(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
329 PyRevision(rev.0).to_py_object(py).into_object()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 48556
diff changeset
330 );
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
331 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
332 Ok(PyList::new(py, missing_pyint_vec.as_slice()))
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
333 }
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
334 });
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
335
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
336 /// Create the module, with __package__ given from parent
40978
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
337 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
338 let dotted_name = &format!("{}.ancestor", package);
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
339 let m = PyModule::new(py, dotted_name)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
340 m.add(py, "__package__", package)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
341 m.add(
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
342 py,
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
343 "__doc__",
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
344 "Generic DAG ancestor algorithms - Rust implementation",
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
345 )?;
41056
d9f439fcdb4c rust-cpython: binding for AncestorsIterator
Georges Racinet <gracinet@anybox.fr>
parents: 40978
diff changeset
346 m.add_class::<AncestorsIterator>(py)?;
41117
b31a41f24864 rust-cpython: binding for LazyAncestors
Georges Racinet <gracinet@anybox.fr>
parents: 41056
diff changeset
347 m.add_class::<LazyAncestors>(py)?;
41188
006c9ce486fa rust-cpython: bindings for MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41187
diff changeset
348 m.add_class::<MissingAncestors>(py)?;
40978
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
349
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
350 let sys = PyModule::import(py, "sys")?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
351 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
352 sys_modules.set_item(py, dotted_name, &m)?;
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
353 // Example C code (see pyexpat.c and import.c) will "give away the
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
354 // reference", but we won't because it will be consumed once the
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
355 // Rust PyObject is dropped.
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
356 Ok(m)
5532823e8c18 rust-cpython: start cpython crate bindings
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
357 }