annotate rust/hg-cpython/src/dagops.rs @ 51196:44fbb7dfb563

rust-index: renamed nodemap error function for rev not in index The function name was misleading, as the error wording mentions the nodemap, hence would not be appropriate for missing revisions not related to a nodemap lookup.
author Georges Racinet <georges.racinet@octobus.net>
date Wed, 18 Oct 2023 19:54:18 +0200
parents 4c5f6e95df84
children 578c049f0408
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
1 // dagops.rs
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
2 //
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
3 // Copyright 2019 Georges Racinet <georges.racinet@octobus.net>
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
4 //
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
5 // This software may be used and distributed according to the terms of the
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
6 // GNU General Public License version 2 or any later version.
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
7
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
8 //! Bindings for the `hg::dagops` module provided by the
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
9 //! `hg-core` package.
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
10 //!
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
11 //! From Python, this will be seen as `mercurial.rustext.dagop`
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
12 use crate::PyRevision;
43945
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43269
diff changeset
13 use crate::{conversion::rev_pyiter_collect, exceptions::GraphError};
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
14 use cpython::{PyDict, PyModule, PyObject, PyResult, Python};
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
15 use hg::dagops;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
16 use hg::Revision;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
17 use std::collections::HashSet;
48854
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
18 use vcsgraph::ancestors::node_rank;
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
19 use vcsgraph::graph::{Parents, Rank};
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
20
43945
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43269
diff changeset
21 use crate::revlog::pyindex_to_graph;
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43269
diff changeset
22
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
23 /// Using the the `index`, return heads out of any Python iterable of Revisions
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
24 ///
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
25 /// This is the Rust counterpart for `mercurial.dagop.headrevs`
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
26 pub fn headrevs(
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
27 py: Python,
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
28 index: PyObject,
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
29 revs: PyObject,
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
30 ) -> PyResult<HashSet<PyRevision>> {
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
31 let index = pyindex_to_graph(py, index)?;
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
32 let mut as_set: HashSet<Revision> = rev_pyiter_collect(py, &revs, &index)?;
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
33 dagops::retain_heads(&index, &mut as_set)
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
34 .map_err(|e| GraphError::pynew(py, e))?;
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
35 Ok(as_set.into_iter().map(Into::into).collect())
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
36 }
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
37
48854
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
38 /// Computes the rank, i.e. the number of ancestors including itself,
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
39 /// of a node represented by its parents.
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
40 pub fn rank(
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
41 py: Python,
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
42 index: PyObject,
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
43 p1r: PyRevision,
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
44 p2r: PyRevision,
48854
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
45 ) -> PyResult<Rank> {
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
46 node_rank(&pyindex_to_graph(py, index)?, &Parents([p1r.0, p2r.0]))
48854
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
47 .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
48 }
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
49
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
50 /// Create the module, with `__package__` given from parent
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
51 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
52 let dotted_name = &format!("{}.dagop", package);
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
53 let m = PyModule::new(py, dotted_name)?;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
54 m.add(py, "__package__", package)?;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
55 m.add(py, "__doc__", "DAG operations - Rust implementation")?;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
56 m.add(
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
57 py,
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
58 "headrevs",
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
59 py_fn!(py, headrevs(index: PyObject, revs: PyObject)),
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
60 )?;
48854
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
61 m.add(
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
62 py,
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
63 "rank",
50976
4c5f6e95df84 rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48854
diff changeset
64 py_fn!(py, rank(index: PyObject, p1r: PyRevision, p2r: PyRevision)),
48854
8b8054b8e5a7 rust: expose rank computation function to python
pacien <pacien.trangirard@pacien.net>
parents: 43945
diff changeset
65 )?;
41694
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
66
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
67 let sys = PyModule::import(py, "sys")?;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
68 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
69 sys_modules.set_item(py, dotted_name, &m)?;
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
70 // Example C code (see pyexpat.c and import.c) will "give away the
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
71 // reference", but we won't because it will be consumed once the
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
72 // Rust PyObject is dropped.
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
73 Ok(m)
0c7b353ce100 rust-cpython: binding for headrevs()
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
74 }