comparison rust/hg-cpython/src/revlog.rs @ 51222:fc05dd74e907

rust-index: add support for `reachableroots2` Exposition in `hg-cpython` done in regular impl block, again for rustfmt support etc.
author Raphaël Gomès <rgomes@octobus.net>
date Mon, 30 Oct 2023 11:57:36 +0100
parents c817d9f626d3
children 89ce6a49bfeb
comparison
equal deleted inserted replaced
51221:5a7d5fd6808c 51222:fc05dd74e907
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")