pyority_queue/src/backing/containers/py_item.rs

46 lines
1.3 KiB
Rust

use std::cmp::Ordering;
use pyo3::prelude::*;
/// Container that provides PartialOrd based on the Python object it holds
#[derive(Debug, Clone)]
pub struct PyItem(Py<PyAny>);
impl PyItem {
/// Creates a new instance
pub fn new(item: Py<PyAny>) -> Self {
PyItem(item)
}
/// Retrieves the internal data
pub fn data(self) -> Py<PyAny> {
self.0
}
}
impl PartialOrd for PyItem {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Python::with_gil(|py| {
// Bind objects for convenience
let ours = self.0.bind(py);
let theirs = other.0.bind(py);
// Compare based on Python comparison implementations
match ours.lt(theirs) {
Ok(true) => Some(Ordering::Less),
Ok(false) => match ours.gt(theirs) {
Ok(true) => Some(Ordering::Greater),
Ok(false) => Some(Ordering::Equal), // If the python class is implemented strangely then this may be wrong
Err(_) => None,
},
Err(_) => None,
}
})
}
}
impl PartialEq for PyItem {
fn eq(&self, other: &Self) -> bool {
Python::with_gil(|py| self.0.bind(py).eq(other.0.bind(py)).unwrap_or(false))
}
}