rust/hg-cpython/src/conversion.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 15 Nov 2024 23:50:35 +0100
branchstable
changeset 52236 81e59988e11c
parent 51242 5a7d5fd6808c
permissions -rw-r--r--
wheels: make sure we create the `dist/` directory in the make target The embarrassing details of how this was discovered will be kept under silence.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
41240
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     1
// conversion.rs
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     2
//
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     3
// Copyright 2019 Georges Racinet <georges.racinet@octobus.net>
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     4
//
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     7
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     8
//! Bindings for the hg::ancestors module provided by the
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     9
//! `hg-core` crate. From Python, this will be seen as `rustext.ancestor`
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    10
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    11
use cpython::{ObjectProtocol, PyErr, PyObject, PyResult, Python};
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    12
use hg::{Revision, RevlogIndex, UncheckedRevision};
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    13
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    14
use crate::{exceptions::GraphError, PyRevision};
41240
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    15
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    16
/// Utility function to convert a Python iterable into various collections
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    17
///
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    18
/// We need this in particular to feed to various methods of inner objects
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    19
/// with `impl IntoIterator<Item=Revision>` arguments, because
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    20
/// a `PyErr` can arise at each step of iteration, whereas these methods
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    21
/// expect iterables over `Revision`, not over some `Result<Revision, PyErr>`
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    22
pub fn rev_pyiter_collect<C, I>(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    23
    py: Python,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    24
    revs: &PyObject,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    25
    index: &I,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    26
) -> PyResult<C>
41240
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    27
where
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    28
    C: FromIterator<Revision>,
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    29
    I: RevlogIndex,
41240
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    30
{
51242
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    31
    rev_pyiter_collect_or_else(py, revs, index, |r| {
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    32
        PyErr::new::<GraphError, _>(py, ("InvalidRevision", r.0))
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    33
    })
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    34
}
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    35
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    36
/// Same as [`rev_pyiter_collect`], giving control on returned errors
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    37
pub fn rev_pyiter_collect_or_else<C, I>(
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    38
    py: Python,
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    39
    revs: &PyObject,
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    40
    index: &I,
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    41
    invalid_rev_error: impl FnOnce(PyRevision) -> PyErr + Copy,
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    42
) -> PyResult<C>
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    43
where
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    44
    C: FromIterator<Revision>,
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    45
    I: RevlogIndex,
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    46
{
41240
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    47
    revs.iter(py)?
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    48
        .map(|r| {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    49
            r.and_then(|o| match o.extract::<PyRevision>(py) {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    50
                Ok(r) => index
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    51
                    .check_revision(UncheckedRevision(r.0))
51242
5a7d5fd6808c hg-cpython: rev_pyiter_collect_or_else
Georges Racinet <georges.racinet@octobus.net>
parents: 50990
diff changeset
    52
                    .ok_or_else(|| invalid_rev_error(r)),
50990
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    53
                Err(e) => Err(e),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    54
            })
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49749
diff changeset
    55
        })
41240
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    56
        .collect()
ff333620a4cc rust-cpython: moved generic conversion fn out of ancestors module
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    57
}