|
1 // discovery.rs |
|
2 // |
|
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr> |
|
4 // |
|
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. |
|
7 |
|
8 //! Bindings for the `hg::discovery` module provided by the |
|
9 //! `hg-core` crate. From Python, this will be seen as `rustext.discovery` |
|
10 //! |
|
11 //! # Classes visible from Python: |
|
12 //! - [`PartialDiscover`] is the Rust implementation of |
|
13 //! `mercurial.setdiscovery.partialdiscovery`. |
|
14 |
|
15 use crate::conversion::{py_set, rev_pyiter_collect}; |
|
16 use cindex::Index; |
|
17 use cpython::{ObjectProtocol, PyDict, PyModule, PyObject, PyResult, Python}; |
|
18 use exceptions::GraphError; |
|
19 use hg::discovery::PartialDiscovery as CorePartialDiscovery; |
|
20 use hg::Revision; |
|
21 |
|
22 use std::cell::RefCell; |
|
23 |
|
24 py_class!(pub class PartialDiscovery |py| { |
|
25 data inner: RefCell<Box<CorePartialDiscovery<Index>>>; |
|
26 |
|
27 def __new__( |
|
28 _cls, |
|
29 index: PyObject, |
|
30 targetheads: PyObject |
|
31 ) -> PyResult<PartialDiscovery> { |
|
32 Self::create_instance( |
|
33 py, |
|
34 RefCell::new(Box::new(CorePartialDiscovery::new( |
|
35 Index::new(py, index)?, |
|
36 rev_pyiter_collect(py, &targetheads)?, |
|
37 ))) |
|
38 ) |
|
39 } |
|
40 |
|
41 def addcommons(&self, commons: PyObject) -> PyResult<PyObject> { |
|
42 let mut inner = self.inner(py).borrow_mut(); |
|
43 let commons_vec: Vec<Revision> = rev_pyiter_collect(py, &commons)?; |
|
44 inner.add_common_revisions(commons_vec) |
|
45 .map_err(|e| GraphError::pynew(py, e))?; |
|
46 Ok(py.None()) |
|
47 } |
|
48 |
|
49 def addmissings(&self, missings: PyObject) -> PyResult<PyObject> { |
|
50 let mut inner = self.inner(py).borrow_mut(); |
|
51 let missings_vec: Vec<Revision> = rev_pyiter_collect(py, &missings)?; |
|
52 inner.add_missing_revisions(missings_vec) |
|
53 .map_err(|e| GraphError::pynew(py, e))?; |
|
54 Ok(py.None()) |
|
55 } |
|
56 |
|
57 def addinfo(&self, sample: PyObject) -> PyResult<PyObject> { |
|
58 let mut missing: Vec<Revision> = Vec::new(); |
|
59 let mut common: Vec<Revision> = Vec::new(); |
|
60 for info in sample.iter(py)? { // info is a pair (Revision, bool) |
|
61 let mut revknown = info?.iter(py)?; |
|
62 let rev: Revision = revknown.next().unwrap()?.extract(py)?; |
|
63 let known: bool = revknown.next().unwrap()?.extract(py)?; |
|
64 if known { |
|
65 common.push(rev); |
|
66 } else { |
|
67 missing.push(rev); |
|
68 } |
|
69 } |
|
70 let mut inner = self.inner(py).borrow_mut(); |
|
71 inner.add_common_revisions(common) |
|
72 .map_err(|e| GraphError::pynew(py, e))?; |
|
73 inner.add_missing_revisions(missing) |
|
74 .map_err(|e| GraphError::pynew(py, e))?; |
|
75 Ok(py.None()) |
|
76 } |
|
77 |
|
78 def hasinfo(&self) -> PyResult<bool> { |
|
79 Ok(self.inner(py).borrow().has_info()) |
|
80 } |
|
81 |
|
82 def iscomplete(&self) -> PyResult<bool> { |
|
83 Ok(self.inner(py).borrow().is_complete()) |
|
84 } |
|
85 |
|
86 def commonheads(&self) -> PyResult<PyObject> { |
|
87 py_set( |
|
88 py, |
|
89 &self.inner(py).borrow().common_heads() |
|
90 .map_err(|e| GraphError::pynew(py, e))? |
|
91 ) |
|
92 } |
|
93 }); |
|
94 |
|
95 /// Create the module, with __package__ given from parent |
|
96 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> { |
|
97 let dotted_name = &format!("{}.discovery", package); |
|
98 let m = PyModule::new(py, dotted_name)?; |
|
99 m.add(py, "__package__", package)?; |
|
100 m.add( |
|
101 py, |
|
102 "__doc__", |
|
103 "Discovery of common node sets - Rust implementation", |
|
104 )?; |
|
105 m.add_class::<PartialDiscovery>(py)?; |
|
106 |
|
107 let sys = PyModule::import(py, "sys")?; |
|
108 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?; |
|
109 sys_modules.set_item(py, dotted_name, &m)?; |
|
110 // Example C code (see pyexpat.c and import.c) will "give away the |
|
111 // reference", but we won't because it will be consumed once the |
|
112 // Rust PyObject is dropped. |
|
113 Ok(m) |
|
114 } |