##// END OF EJS Templates
rust: fix cargo doc for hg-cpython
Georges Racinet -
r52078:a6e293b2 default
parent child Browse files
Show More
@@ -1,173 +1,173 b''
1 // discovery.rs
1 // discovery.rs
2 //
2 //
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
4 //
4 //
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 //! Bindings for the `hg::discovery` module provided by the
8 //! Bindings for the `hg::discovery` module provided by the
9 //! `hg-core` crate. From Python, this will be seen as `rustext.discovery`
9 //! `hg-core` crate. From Python, this will be seen as `rustext.discovery`
10 //!
10 //!
11 //! # Classes visible from Python:
11 //! # Classes visible from Python:
12 //! - [`PartialDiscover`] is the Rust implementation of
12 //! - [`PartialDiscovery`] is the Rust implementation of
13 //! `mercurial.setdiscovery.partialdiscovery`.
13 //! `mercurial.setdiscovery.partialdiscovery`.
14
14
15 use crate::PyRevision;
15 use crate::PyRevision;
16 use crate::{
16 use crate::{
17 cindex::Index, conversion::rev_pyiter_collect, exceptions::GraphError,
17 cindex::Index, conversion::rev_pyiter_collect, exceptions::GraphError,
18 };
18 };
19 use cpython::{
19 use cpython::{
20 ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple,
20 ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple,
21 Python, PythonObject, ToPyObject,
21 Python, PythonObject, ToPyObject,
22 };
22 };
23 use hg::discovery::PartialDiscovery as CorePartialDiscovery;
23 use hg::discovery::PartialDiscovery as CorePartialDiscovery;
24 use hg::Revision;
24 use hg::Revision;
25 use std::collections::HashSet;
25 use std::collections::HashSet;
26
26
27 use std::cell::RefCell;
27 use std::cell::RefCell;
28
28
29 use crate::revlog::pyindex_to_graph;
29 use crate::revlog::pyindex_to_graph;
30
30
31 py_class!(pub class PartialDiscovery |py| {
31 py_class!(pub class PartialDiscovery |py| {
32 data inner: RefCell<Box<CorePartialDiscovery<Index>>>;
32 data inner: RefCell<Box<CorePartialDiscovery<Index>>>;
33 data index: RefCell<Index>;
33 data index: RefCell<Index>;
34
34
35 // `_respectsize` is currently only here to replicate the Python API and
35 // `_respectsize` is currently only here to replicate the Python API and
36 // will be used in future patches inside methods that are yet to be
36 // will be used in future patches inside methods that are yet to be
37 // implemented.
37 // implemented.
38 def __new__(
38 def __new__(
39 _cls,
39 _cls,
40 repo: PyObject,
40 repo: PyObject,
41 targetheads: PyObject,
41 targetheads: PyObject,
42 respectsize: bool,
42 respectsize: bool,
43 randomize: bool = true
43 randomize: bool = true
44 ) -> PyResult<PartialDiscovery> {
44 ) -> PyResult<PartialDiscovery> {
45 let index = repo.getattr(py, "changelog")?.getattr(py, "index")?;
45 let index = repo.getattr(py, "changelog")?.getattr(py, "index")?;
46 let index = pyindex_to_graph(py, index)?;
46 let index = pyindex_to_graph(py, index)?;
47 let target_heads = rev_pyiter_collect(py, &targetheads, &index)?;
47 let target_heads = rev_pyiter_collect(py, &targetheads, &index)?;
48 Self::create_instance(
48 Self::create_instance(
49 py,
49 py,
50 RefCell::new(Box::new(CorePartialDiscovery::new(
50 RefCell::new(Box::new(CorePartialDiscovery::new(
51 index.clone_ref(py),
51 index.clone_ref(py),
52 target_heads,
52 target_heads,
53 respectsize,
53 respectsize,
54 randomize,
54 randomize,
55 ))),
55 ))),
56 RefCell::new(index),
56 RefCell::new(index),
57 )
57 )
58 }
58 }
59
59
60 def addcommons(&self, commons: PyObject) -> PyResult<PyObject> {
60 def addcommons(&self, commons: PyObject) -> PyResult<PyObject> {
61 let index = self.index(py).borrow();
61 let index = self.index(py).borrow();
62 let commons_vec: Vec<_> = rev_pyiter_collect(py, &commons, &*index)?;
62 let commons_vec: Vec<_> = rev_pyiter_collect(py, &commons, &*index)?;
63 let mut inner = self.inner(py).borrow_mut();
63 let mut inner = self.inner(py).borrow_mut();
64 inner.add_common_revisions(commons_vec)
64 inner.add_common_revisions(commons_vec)
65 .map_err(|e| GraphError::pynew(py, e))?;
65 .map_err(|e| GraphError::pynew(py, e))?;
66 Ok(py.None())
66 Ok(py.None())
67 }
67 }
68
68
69 def addmissings(&self, missings: PyObject) -> PyResult<PyObject> {
69 def addmissings(&self, missings: PyObject) -> PyResult<PyObject> {
70 let index = self.index(py).borrow();
70 let index = self.index(py).borrow();
71 let missings_vec: Vec<_> = rev_pyiter_collect(py, &missings, &*index)?;
71 let missings_vec: Vec<_> = rev_pyiter_collect(py, &missings, &*index)?;
72 let mut inner = self.inner(py).borrow_mut();
72 let mut inner = self.inner(py).borrow_mut();
73 inner.add_missing_revisions(missings_vec)
73 inner.add_missing_revisions(missings_vec)
74 .map_err(|e| GraphError::pynew(py, e))?;
74 .map_err(|e| GraphError::pynew(py, e))?;
75 Ok(py.None())
75 Ok(py.None())
76 }
76 }
77
77
78 def addinfo(&self, sample: PyObject) -> PyResult<PyObject> {
78 def addinfo(&self, sample: PyObject) -> PyResult<PyObject> {
79 let mut missing: Vec<Revision> = Vec::new();
79 let mut missing: Vec<Revision> = Vec::new();
80 let mut common: Vec<Revision> = Vec::new();
80 let mut common: Vec<Revision> = Vec::new();
81 for info in sample.iter(py)? { // info is a pair (Revision, bool)
81 for info in sample.iter(py)? { // info is a pair (Revision, bool)
82 let mut revknown = info?.iter(py)?;
82 let mut revknown = info?.iter(py)?;
83 let rev: PyRevision = revknown.next().unwrap()?.extract(py)?;
83 let rev: PyRevision = revknown.next().unwrap()?.extract(py)?;
84 // This is fine since we're just using revisions as integers
84 // This is fine since we're just using revisions as integers
85 // for the purposes of discovery
85 // for the purposes of discovery
86 let rev = Revision(rev.0);
86 let rev = Revision(rev.0);
87 let known: bool = revknown.next().unwrap()?.extract(py)?;
87 let known: bool = revknown.next().unwrap()?.extract(py)?;
88 if known {
88 if known {
89 common.push(rev);
89 common.push(rev);
90 } else {
90 } else {
91 missing.push(rev);
91 missing.push(rev);
92 }
92 }
93 }
93 }
94 let mut inner = self.inner(py).borrow_mut();
94 let mut inner = self.inner(py).borrow_mut();
95 inner.add_common_revisions(common)
95 inner.add_common_revisions(common)
96 .map_err(|e| GraphError::pynew(py, e))?;
96 .map_err(|e| GraphError::pynew(py, e))?;
97 inner.add_missing_revisions(missing)
97 inner.add_missing_revisions(missing)
98 .map_err(|e| GraphError::pynew(py, e))?;
98 .map_err(|e| GraphError::pynew(py, e))?;
99 Ok(py.None())
99 Ok(py.None())
100 }
100 }
101
101
102 def hasinfo(&self) -> PyResult<bool> {
102 def hasinfo(&self) -> PyResult<bool> {
103 Ok(self.inner(py).borrow().has_info())
103 Ok(self.inner(py).borrow().has_info())
104 }
104 }
105
105
106 def iscomplete(&self) -> PyResult<bool> {
106 def iscomplete(&self) -> PyResult<bool> {
107 Ok(self.inner(py).borrow().is_complete())
107 Ok(self.inner(py).borrow().is_complete())
108 }
108 }
109
109
110 def stats(&self) -> PyResult<PyDict> {
110 def stats(&self) -> PyResult<PyDict> {
111 let stats = self.inner(py).borrow().stats();
111 let stats = self.inner(py).borrow().stats();
112 let as_dict: PyDict = PyDict::new(py);
112 let as_dict: PyDict = PyDict::new(py);
113 as_dict.set_item(py, "undecided",
113 as_dict.set_item(py, "undecided",
114 stats.undecided.map(
114 stats.undecided.map(
115 |l| l.to_py_object(py).into_object())
115 |l| l.to_py_object(py).into_object())
116 .unwrap_or_else(|| py.None()))?;
116 .unwrap_or_else(|| py.None()))?;
117 Ok(as_dict)
117 Ok(as_dict)
118 }
118 }
119
119
120 def commonheads(&self) -> PyResult<HashSet<PyRevision>> {
120 def commonheads(&self) -> PyResult<HashSet<PyRevision>> {
121 let res = self.inner(py).borrow().common_heads()
121 let res = self.inner(py).borrow().common_heads()
122 .map_err(|e| GraphError::pynew(py, e))?;
122 .map_err(|e| GraphError::pynew(py, e))?;
123 Ok(res.into_iter().map(Into::into).collect())
123 Ok(res.into_iter().map(Into::into).collect())
124 }
124 }
125
125
126 def takefullsample(&self, _headrevs: PyObject,
126 def takefullsample(&self, _headrevs: PyObject,
127 size: usize) -> PyResult<PyObject> {
127 size: usize) -> PyResult<PyObject> {
128 let mut inner = self.inner(py).borrow_mut();
128 let mut inner = self.inner(py).borrow_mut();
129 let sample = inner.take_full_sample(size)
129 let sample = inner.take_full_sample(size)
130 .map_err(|e| GraphError::pynew(py, e))?;
130 .map_err(|e| GraphError::pynew(py, e))?;
131 let as_vec: Vec<PyObject> = sample
131 let as_vec: Vec<PyObject> = sample
132 .iter()
132 .iter()
133 .map(|rev| PyRevision(rev.0).to_py_object(py).into_object())
133 .map(|rev| PyRevision(rev.0).to_py_object(py).into_object())
134 .collect();
134 .collect();
135 Ok(PyTuple::new(py, as_vec.as_slice()).into_object())
135 Ok(PyTuple::new(py, as_vec.as_slice()).into_object())
136 }
136 }
137
137
138 def takequicksample(&self, headrevs: PyObject,
138 def takequicksample(&self, headrevs: PyObject,
139 size: usize) -> PyResult<PyObject> {
139 size: usize) -> PyResult<PyObject> {
140 let index = self.index(py).borrow();
140 let index = self.index(py).borrow();
141 let mut inner = self.inner(py).borrow_mut();
141 let mut inner = self.inner(py).borrow_mut();
142 let revsvec: Vec<_> = rev_pyiter_collect(py, &headrevs, &*index)?;
142 let revsvec: Vec<_> = rev_pyiter_collect(py, &headrevs, &*index)?;
143 let sample = inner.take_quick_sample(revsvec, size)
143 let sample = inner.take_quick_sample(revsvec, size)
144 .map_err(|e| GraphError::pynew(py, e))?;
144 .map_err(|e| GraphError::pynew(py, e))?;
145 let as_vec: Vec<PyObject> = sample
145 let as_vec: Vec<PyObject> = sample
146 .iter()
146 .iter()
147 .map(|rev| PyRevision(rev.0).to_py_object(py).into_object())
147 .map(|rev| PyRevision(rev.0).to_py_object(py).into_object())
148 .collect();
148 .collect();
149 Ok(PyTuple::new(py, as_vec.as_slice()).into_object())
149 Ok(PyTuple::new(py, as_vec.as_slice()).into_object())
150 }
150 }
151
151
152 });
152 });
153
153
154 /// Create the module, with __package__ given from parent
154 /// Create the module, with __package__ given from parent
155 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
155 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
156 let dotted_name = &format!("{}.discovery", package);
156 let dotted_name = &format!("{}.discovery", package);
157 let m = PyModule::new(py, dotted_name)?;
157 let m = PyModule::new(py, dotted_name)?;
158 m.add(py, "__package__", package)?;
158 m.add(py, "__package__", package)?;
159 m.add(
159 m.add(
160 py,
160 py,
161 "__doc__",
161 "__doc__",
162 "Discovery of common node sets - Rust implementation",
162 "Discovery of common node sets - Rust implementation",
163 )?;
163 )?;
164 m.add_class::<PartialDiscovery>(py)?;
164 m.add_class::<PartialDiscovery>(py)?;
165
165
166 let sys = PyModule::import(py, "sys")?;
166 let sys = PyModule::import(py, "sys")?;
167 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
167 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
168 sys_modules.set_item(py, dotted_name, &m)?;
168 sys_modules.set_item(py, dotted_name, &m)?;
169 // Example C code (see pyexpat.c and import.c) will "give away the
169 // Example C code (see pyexpat.c and import.c) will "give away the
170 // reference", but we won't because it will be consumed once the
170 // reference", but we won't because it will be consumed once the
171 // Rust PyObject is dropped.
171 // Rust PyObject is dropped.
172 Ok(m)
172 Ok(m)
173 }
173 }
General Comments 0
You need to be logged in to leave comments. Login now