Mercurial > public > mercurial-scm > hg
annotate rust/hg-cpython/src/cindex.rs @ 52696:10e7adbffa8c
streamclone: unbyteify string args to builtin Error classes
This avoids printing the error with a `b''` prefix in the case of `ValueError`.
The custom `ProgrammingError` class is special in that it won't do that, and can
take either bytes or str. But there's no point in passing bytes when it is just
going to decode to str at runtime anyway.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Mon, 13 Jan 2025 00:40:48 -0500 |
parents | 96e05f1a99bd |
children | 2fb13c3f4496 |
rev | line source |
---|---|
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
1 // cindex.rs |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
2 // |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr> |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
4 // |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
5 // This software may be used and distributed according to the terms of the |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
6 // GNU General Public License version 2 or any later version. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
7 |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
8 //! Bindings to use the Index defined by the parsers C extension |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
9 //! |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
10 //! Ideally, we should use an Index entirely implemented in Rust, |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
11 //! but this will take some time to get there. |
51250
96e05f1a99bd
rust-index: stop instantiating a C Index
Georges Racinet <georges.racinet@octobus.net>
parents:
50976
diff
changeset
|
12 #![allow(dead_code)] |
44504
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
13 use cpython::{ |
47268
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
14 exc::ImportError, exc::TypeError, ObjectProtocol, PyClone, PyErr, |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
15 PyObject, PyResult, PyTuple, Python, PythonObject, |
44504
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
16 }; |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
17 use hg::revlog::{Node, RevlogIndex}; |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
18 use hg::{BaseRevision, Graph, GraphError, Revision}; |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
19 use libc::{c_int, ssize_t}; |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
20 |
48852
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
21 const REVLOG_CABI_VERSION: c_int = 3; |
44066
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
22 |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
23 #[repr(C)] |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
24 pub struct Revlog_CAPI { |
44066
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
25 abi_version: c_int, |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
26 index_length: |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
27 unsafe extern "C" fn(index: *mut revlog_capi::RawPyObject) -> ssize_t, |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
28 index_node: unsafe extern "C" fn( |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
29 index: *mut revlog_capi::RawPyObject, |
46412
7d0405e458a0
persistent-nodemap: Fix Rust declarations for Revlog_CAPI signatures
Simon Sapin <simon.sapin@octobus.net>
parents:
44973
diff
changeset
|
30 rev: ssize_t, |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
31 ) -> *const Node, |
48852
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
32 fast_rank: unsafe extern "C" fn( |
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
33 index: *mut revlog_capi::RawPyObject, |
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
34 rev: ssize_t, |
e633e660158f
revlog: implement fast_rank retrieval in C
pacien <pacien.trangirard@pacien.net>
parents:
48518
diff
changeset
|
35 ) -> ssize_t, |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
36 index_parents: unsafe extern "C" fn( |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
37 index: *mut revlog_capi::RawPyObject, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
38 rev: c_int, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
39 ps: *mut [c_int; 2], |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
40 ) -> c_int, |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
41 } |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
42 |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
43 py_capsule!( |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
44 from mercurial.cext.parsers import revlog_CAPI |
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
45 as revlog_capi for Revlog_CAPI); |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
46 |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
47 /// A `Graph` backed up by objects and functions from revlog.c |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
48 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
49 /// This implementation of the `Graph` trait, relies on (pointers to) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
50 /// - the C index object (`index` member) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
51 /// - the `index_get_parents()` function (`parents` member) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
52 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
53 /// # Safety |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
54 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
55 /// The C index itself is mutable, and this Rust exposition is **not |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
56 /// protected by the GIL**, meaning that this construct isn't safe with respect |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
57 /// to Python threads. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
58 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
59 /// All callers of this `Index` must acquire the GIL and must not release it |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
60 /// while working. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
61 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
62 /// # TODO find a solution to make it GIL safe again. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
63 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
64 /// This is non trivial, and can wait until we have a clearer picture with |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
65 /// more Rust Mercurial constructs. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
66 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
67 /// One possibility would be to a `GILProtectedIndex` wrapper enclosing |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
68 /// a `Python<'p>` marker and have it be the one implementing the |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
69 /// `Graph` trait, but this would mean the `Graph` implementor would become |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
70 /// likely to change between subsequent method invocations of the `hg-core` |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
71 /// objects (a serious change of the `hg-core` API): |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
72 /// either exposing ways to mutate the `Graph`, or making it a non persistent |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
73 /// parameter in the relevant methods that need one. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
74 /// |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
75 /// Another possibility would be to introduce an abstract lock handle into |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
76 /// the core API, that would be tied to `GILGuard` / `Python<'p>` |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
77 /// in the case of the `cpython` crate bindings yet could leave room for other |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
78 /// mechanisms in other contexts. |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
79 pub struct Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
80 index: PyObject, |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
81 capi: &'static Revlog_CAPI, |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
82 } |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
83 |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
84 impl Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
85 pub fn new(py: Python, index: PyObject) -> PyResult<Self> { |
44066
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
86 let capi = unsafe { revlog_capi::retrieve(py)? }; |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
87 if capi.abi_version != REVLOG_CABI_VERSION { |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
88 return Err(PyErr::new::<ImportError, _>( |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
89 py, |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
90 format!( |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
91 "ABI version mismatch: the C ABI revlog version {} \ |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
92 does not match the {} expected by Rust hg-cpython", |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
93 capi.abi_version, REVLOG_CABI_VERSION |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
94 ), |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
95 )); |
f5d2720f3bea
revlog-native: introduced ABI version in capsule
Georges Racinet <georges.racinet@octobus.net>
parents:
44010
diff
changeset
|
96 } |
47268
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
97 let compat: u64 = index.getattr(py, "rust_ext_compat")?.extract(py)?; |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
98 if compat == 0 { |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
99 return Err(PyErr::new::<TypeError, _>( |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
100 py, |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
101 "index object not compatible with Rust", |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
102 )); |
9d1a8829f959
revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46412
diff
changeset
|
103 } |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44504
diff
changeset
|
104 Ok(Index { index, capi }) |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
105 } |
43960
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
106 |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
107 /// return a reference to the CPython Index object in this Struct |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
108 pub fn inner(&self) -> &PyObject { |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
109 &self.index |
ab3fd8077f5e
rust-index: add a `inner` method to the Index struct
Georges Racinet <georges.racinet@octobus.net>
parents:
43959
diff
changeset
|
110 } |
44504
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
111 |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
112 pub fn append(&mut self, py: Python, tup: PyTuple) -> PyResult<PyObject> { |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
113 self.index.call_method( |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
114 py, |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
115 "append", |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
116 PyTuple::new(py, &[tup.into_object()]), |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
117 None, |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
118 ) |
cefd130c98be
rust-index: add `append` method to cindex/Index
Georges Racinet <georges.racinet@octobus.net>
parents:
44502
diff
changeset
|
119 } |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
120 } |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
121 |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
122 impl Clone for Index { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
123 fn clone(&self) -> Self { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
124 let guard = Python::acquire_gil(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
125 Index { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
126 index: self.index.clone_ref(guard.python()), |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
127 capi: self.capi, |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
128 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
129 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
130 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
41052
diff
changeset
|
131 |
44010
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
132 impl PyClone for Index { |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
133 fn clone_ref(&self, py: Python) -> Self { |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
134 Index { |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
135 index: self.index.clone_ref(py), |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
136 capi: self.capi, |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
137 } |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
138 } |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
139 } |
2728fcb8127c
rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents:
43960
diff
changeset
|
140 |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
141 impl Graph for Index { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
142 /// wrap a call to the C extern parents function |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
143 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
144 let mut res: [c_int; 2] = [0; 2]; |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
145 let code = unsafe { |
43959
f384d68d8ea8
revlog: made C Capsule an array of function pointers
Georges Racinet <georges.racinet@octobus.net>
parents:
43213
diff
changeset
|
146 (self.capi.index_parents)( |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
147 self.index.as_ptr(), |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
148 rev.0 as c_int, |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
149 &mut res as *mut [c_int; 2], |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
150 ) |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
151 }; |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
152 match code { |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
153 0 => Ok([Revision(res[0]), Revision(res[1])]), |
41052
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
154 _ => Err(GraphError::ParentOutOfRange(rev)), |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
155 } |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
156 } |
4c25038c112c
rust-cpython: implement Graph using C parents function
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
157 } |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
158 |
48518
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
159 impl vcsgraph::graph::Graph for Index { |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
160 fn parents( |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
161 &self, |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
162 rev: BaseRevision, |
48518
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
163 ) -> Result<vcsgraph::graph::Parents, vcsgraph::graph::GraphReadError> |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
164 { |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
165 // FIXME This trait should be reworked to decide between Revision |
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
166 // and UncheckedRevision, get better errors names, etc. |
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
167 match Graph::parents(self, Revision(rev)) { |
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
168 Ok(parents) => { |
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
169 Ok(vcsgraph::graph::Parents([parents[0].0, parents[1].0])) |
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
170 } |
48518
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
171 Err(GraphError::ParentOutOfRange(rev)) => { |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
172 Err(vcsgraph::graph::GraphReadError::KeyedInvalidKey(rev.0)) |
48518
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
173 } |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
174 } |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
175 } |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
176 } |
8e8737a1fa7d
hg-cpython: implement vcsgraph::Graph for our Index
pacien <pacien.trangirard@pacien.net>
parents:
47268
diff
changeset
|
177 |
48853
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
178 impl vcsgraph::graph::RankedGraph for Index { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
179 fn rank( |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
180 &self, |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
181 rev: BaseRevision, |
48853
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
182 ) -> Result<vcsgraph::graph::Rank, vcsgraph::graph::GraphReadError> { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
183 match unsafe { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
184 (self.capi.fast_rank)(self.index.as_ptr(), rev as ssize_t) |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
185 } { |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
186 -1 => Err(vcsgraph::graph::GraphReadError::InconsistentGraphData), |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
187 rank => Ok(rank as usize), |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
188 } |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
189 } |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
190 } |
4346be456875
rust: implement vcsgraph::RankedGraph for Index
pacien <pacien.trangirard@pacien.net>
parents:
48852
diff
changeset
|
191 |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
192 impl RevlogIndex for Index { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
193 /// Note C return type is Py_ssize_t (hence signed), but we shall |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
194 /// force it to unsigned, because it's a length |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
195 fn len(&self) -> usize { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
196 unsafe { (self.capi.index_length)(self.index.as_ptr()) as usize } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
197 } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
198 |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44504
diff
changeset
|
199 fn node(&self, rev: Revision) -> Option<&Node> { |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
200 let raw = unsafe { |
50976
4c5f6e95df84
rust: make `Revision` a newtype
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50972
diff
changeset
|
201 (self.capi.index_node)(self.index.as_ptr(), rev.0 as ssize_t) |
44502
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
202 }; |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
203 if raw.is_null() { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
204 None |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
205 } else { |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
206 // TODO it would be much better for the C layer to give us |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
207 // a length, since the hash length will change in the near |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
208 // future, but that's probably out of scope for the nodemap |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
209 // patch series. |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
210 // |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
211 // The root of that unsafety relies in the signature of |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
212 // `capi.index_node()` itself: returning a `Node` pointer |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
213 // whereas it's a `char *` in the C counterpart. |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
214 Some(unsafe { &*raw }) |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
215 } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
216 } |
166349510398
revlog: using two new functions in C capsule from Rust code
Georges Racinet <georges.racinet@octobus.net>
parents:
44066
diff
changeset
|
217 } |