##// END OF EJS Templates
rust-pyo3: simplified API to get core Index references...
rust-pyo3: simplified API to get core Index references Given the amount of conversion and arcane internal detail, it is easier for the caller and makes a better separation of concerns to just introduce a new unsafe helper. It is actually possible that it would be safe, and we can decide about that later. Actually the reason given in the `cpython` crate for unsafety of the `try_borrow()` method is the following: ``` // try_borrow() and try_borrow_mut() are unsafe because self.data may // have a function returning the inner &'static reference. // If T is &'static U, its lifetime can be easily coerced to &'a U, but // how could we do that for Whatever<'static> in general? ``` Given that we coerce the Index reference to the GIL lifetime and that it is unlikely that the inner data would contain a function returning the a `'static` reference, it is possible that it is actually even safe.

File last commit:

r53311:23370710 default
r53311:23370710 default
Show More
dagops.rs
67 lines | 2.1 KiB | application/rls-services+xml | RustLexer
// dagops.rs
//
// Copyright 2024 Georges Racinet <georges.racinet@cloudcrane.io>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
//! Bindings for the `hg::dagops` module provided by the
//! `hg-core` package.
//!
//! From Python, this will be seen as `mercurial.pyo3-rustext.dagop`
use pyo3::prelude::*;
use std::collections::HashSet;
use hg::{dagops, Revision};
use crate::convert_cpython::proxy_index_extract;
use crate::exceptions::GraphError;
use crate::revision::{rev_pyiter_collect, PyRevision};
use crate::util::new_submodule;
/// Using the the `index_proxy`, return heads out of any Python iterable of
/// Revisions
///
/// This is the Rust counterpart for `mercurial.dagop.headrevs`
#[pyfunction]
pub fn headrevs(
index_proxy: &Bound<'_, PyAny>,
revs: &Bound<'_, PyAny>,
) -> PyResult<HashSet<PyRevision>> {
// Safety: we don't leak the "faked" reference out of `UnsafePyLeaked`
let index = unsafe { proxy_index_extract(index_proxy)? };
let mut as_set: HashSet<Revision> = rev_pyiter_collect(revs, index)?;
dagops::retain_heads(index, &mut as_set).map_err(GraphError::from_hg)?;
Ok(as_set.into_iter().map(Into::into).collect())
}
/// Computes the rank, i.e. the number of ancestors including itself,
/// of a node represented by its parents.
///
/// Currently, the pure Rust index supports only the REVLOGV1 format, hence
/// the only possible return value is that the rank is unknown.
///
/// References:
/// - C implementation, function `index_fast_rank()`.
/// - `impl vcsgraph::graph::RankedGraph for Index` in `crate::cindex`.
#[pyfunction]
pub fn rank(
_index: &Bound<'_, PyAny>,
_p1r: PyRevision,
_p2r: PyRevision,
) -> PyResult<()> {
Err(GraphError::from_vcsgraph(
vcsgraph::graph::GraphReadError::InconsistentGraphData,
))
}
pub fn init_module<'py>(
py: Python<'py>,
package: &str,
) -> PyResult<Bound<'py, PyModule>> {
let m = new_submodule(py, package, "dagop")?;
m.add_function(wrap_pyfunction!(headrevs, &m)?)?;
m.add_function(wrap_pyfunction!(rank, &m)?)?;
Ok(m)
}