Mercurial > public > mercurial-scm > hg
annotate rust/hg-pyo3/src/revision.rs @ 52534:9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
The pattern to borrow the core `Index` from the index proxy, and
using it in `rev_pyiter_collect` is frequent enough in what remains
to be converted from `hg-cpython` that it is worth having this direct
helper (and it will neatly enclose the unsafety).
author | Georges Racinet <georges.racinet@cloudcrane.io> |
---|---|
date | Sat, 07 Dec 2024 14:55:42 +0100 |
parents | a642c0a3860f |
children | 1b9907575768 |
rev | line source |
---|---|
52409
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
1 use pyo3::prelude::*; |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
2 |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
3 use hg::revlog::RevlogIndex; |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
4 use hg::{BaseRevision, Revision, UncheckedRevision}; |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
5 |
52534
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
6 use crate::convert_cpython::proxy_index_extract; |
52409
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
7 use crate::exceptions::GraphError; |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
8 |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
9 /// Revision as exposed to/from the Python layer. |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
10 /// |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
11 /// We need this indirection because of the orphan rule, meaning we can't |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
12 /// implement a foreign trait (like [`cpython::ToPyObject`]) |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
13 /// for a foreign type (like [`hg::UncheckedRevision`]). |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
14 /// |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
15 /// This also acts as a deterrent against blindly trusting Python to send |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
16 /// us valid revision numbers. |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
17 #[derive( |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
18 Debug, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
19 Copy, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
20 Clone, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
21 PartialEq, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
22 Eq, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
23 PartialOrd, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
24 Ord, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
25 Hash, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
26 derive_more::From, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
27 IntoPyObject, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
28 FromPyObject, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
29 )] |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
30 pub struct PyRevision(pub BaseRevision); |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
31 |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
32 impl From<Revision> for PyRevision { |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
33 fn from(r: Revision) -> Self { |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
34 PyRevision(r.0) |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
35 } |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
36 } |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
37 |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
38 /// Utility function to convert a Python iterable into various collections |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
39 /// |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
40 /// We need this in particular |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
41 /// - because of the checked upgrade from [`PyRevision`] to [`Revision`]. |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
42 /// - to feed to various methods of inner objects with `impl |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
43 /// IntoIterator<Item=Revision>` arguments, because a `PyErr` can arise at |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
44 /// each step of iteration, whereas these methods expect iterables over |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
45 /// `Revision`, not over some `Result<Revision, PyErr>` |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
46 pub fn rev_pyiter_collect<C, I>( |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
47 revs: &Bound<'_, PyAny>, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
48 index: &I, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
49 ) -> PyResult<C> |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
50 where |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
51 C: FromIterator<Revision>, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
52 I: RevlogIndex, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
53 { |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
54 rev_pyiter_collect_or_else(revs, index, |r| { |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
55 PyErr::new::<GraphError, _>(("InvalidRevision", r.0)) |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
56 }) |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
57 } |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
58 |
52534
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
59 pub fn rev_pyiter_collect_with_py_index<C>( |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
60 revs: &Bound<'_, PyAny>, |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
61 proxy_index: &Bound<'_, PyAny>, |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
62 ) -> PyResult<C> |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
63 where |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
64 C: FromIterator<Revision>, |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
65 { |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
66 // Safety: we don't leak the "faked" reference out of `UnsafePyLeaked` |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
67 let borrowed_idx = unsafe { proxy_index_extract(proxy_index)? }; |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
68 rev_pyiter_collect(revs, borrowed_idx) |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
69 } |
9af0330788a5
rust-pyo3: new helper for incoming iterables of revisions
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52409
diff
changeset
|
70 |
52409
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
71 /// Same as [`rev_pyiter_collect`], giving control on returned errors |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
72 pub fn rev_pyiter_collect_or_else<C, I>( |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
73 revs: &Bound<'_, PyAny>, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
74 index: &I, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
75 invalid_rev_error: impl FnOnce(PyRevision) -> PyErr + Copy, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
76 ) -> PyResult<C> |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
77 where |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
78 C: FromIterator<Revision>, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
79 I: RevlogIndex, |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
80 { |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
81 revs.try_iter()? |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
82 .map(|r| { |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
83 r.and_then(|o| match o.extract::<PyRevision>() { |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
84 Ok(r) => index |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
85 .check_revision(UncheckedRevision(r.0)) |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
86 .ok_or_else(|| invalid_rev_error(r)), |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
87 Err(e) => Err(e), |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
88 }) |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
89 }) |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
90 .collect() |
a642c0a3860f
rust-pyo3: conversion helpers for Revision objects
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
diff
changeset
|
91 } |