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); impl PyItem { /// Creates a new instance pub fn new(item: Py) -> Self { PyItem(item) } /// Retrieves the internal data pub fn data(self) -> Py { self.0 } } impl PartialOrd for PyItem { fn partial_cmp(&self, other: &Self) -> Option { 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)) } }