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 use crate::{ |
8 use crate::{ |
9 cindex, |
9 cindex, |
10 conversion::rev_pyiter_collect, |
10 conversion::{rev_pyiter_collect, rev_pyiter_collect_or_else}, |
11 utils::{node_from_py_bytes, node_from_py_object}, |
11 utils::{node_from_py_bytes, node_from_py_object}, |
12 PyRevision, |
12 PyRevision, |
13 }; |
13 }; |
14 use cpython::{ |
14 use cpython::{ |
15 buffer::{Element, PyBuffer}, |
15 buffer::{Element, PyBuffer}, |
249 Ok(rust_res) |
249 Ok(rust_res) |
250 } |
250 } |
251 |
251 |
252 /// reachableroots |
252 /// reachableroots |
253 def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> { |
253 def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> { |
254 self.call_cindex(py, "reachableroots2", args, kw) |
254 let rust_res = self.inner_reachableroots2( |
|
255 py, |
|
256 UncheckedRevision(args.get_item(py, 0).extract(py)?), |
|
257 args.get_item(py, 1), |
|
258 args.get_item(py, 2), |
|
259 args.get_item(py, 3).extract(py)?, |
|
260 )?; |
|
261 |
|
262 let c_res = self.call_cindex(py, "reachableroots2", args, kw)?; |
|
263 // ordering of C result depends on how the computation went, and |
|
264 // Rust result ordering is arbitrary. Hence we compare after |
|
265 // sorting the results (in Python to avoid reconverting everything |
|
266 // back to Rust structs). |
|
267 assert_py_eq_normalized(py, "reachableroots2", &rust_res, &c_res, |
|
268 |v| format!("sorted({})", v))?; |
|
269 |
|
270 Ok(rust_res) |
255 } |
271 } |
256 |
272 |
257 /// get head revisions |
273 /// get head revisions |
258 def headrevs(&self, *args, **kw) -> PyResult<PyObject> { |
274 def headrevs(&self, *args, **kw) -> PyResult<PyObject> { |
259 let rust_res = self.inner_headrevs(py)?; |
275 let rust_res = self.inner_headrevs(py)?; |
927 Ok(PyTuple::new(py, &res).into_object()) |
943 Ok(PyTuple::new(py, &res).into_object()) |
928 } else { |
944 } else { |
929 Ok(PyList::new(py, &res).into_object()) |
945 Ok(PyList::new(py, &res).into_object()) |
930 } |
946 } |
931 } |
947 } |
|
948 |
|
949 fn inner_reachableroots2( |
|
950 &self, |
|
951 py: Python, |
|
952 min_root: UncheckedRevision, |
|
953 heads: PyObject, |
|
954 roots: PyObject, |
|
955 include_path: bool, |
|
956 ) -> PyResult<PyObject> { |
|
957 let index = &*self.index(py).borrow(); |
|
958 let heads = rev_pyiter_collect_or_else(py, &heads, index, |_rev| { |
|
959 PyErr::new::<IndexError, _>(py, "head out of range") |
|
960 })?; |
|
961 let roots: Result<_, _> = roots |
|
962 .iter(py)? |
|
963 .map(|r| { |
|
964 r.and_then(|o| match o.extract::<PyRevision>(py) { |
|
965 Ok(r) => Ok(UncheckedRevision(r.0)), |
|
966 Err(e) => Err(e), |
|
967 }) |
|
968 }) |
|
969 .collect(); |
|
970 let as_set = index |
|
971 .reachable_roots(min_root, heads, roots?, include_path) |
|
972 .map_err(|e| graph_error(py, e))?; |
|
973 let as_vec: Vec<PyObject> = as_set |
|
974 .iter() |
|
975 .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) |
|
976 .collect(); |
|
977 Ok(PyList::new(py, &as_vec).into_object()) |
|
978 } |
932 } |
979 } |
933 |
980 |
934 fn revlog_error(py: Python) -> PyErr { |
981 fn revlog_error(py: Python) -> PyErr { |
935 match py |
982 match py |
936 .import("mercurial.error") |
983 .import("mercurial.error") |