use crate::{
algorithms::bipartite::max_weight_matching::Matching,
db::{
api::view::{DynamicGraph, IntoDynamic, StaticGraphViewOps},
graph::{edge::EdgeView, edges::Edges, node::NodeView},
},
prelude::GraphViewOps,
python::{
types::{repr::Repr, wrappers::iterators::PyBorrowingIterator},
utils::PyNodeRef,
},
};
use pyo3::prelude::*;
#[pyclass(frozen, name = "Matching", module = "raphtory.algorithms")]
pub struct PyMatching {
inner: Matching<DynamicGraph>,
}
impl<'py, G: StaticGraphViewOps + IntoDynamic> IntoPyObject<'py> for Matching<G> {
type Target = PyMatching;
type Output = Bound<'py, PyMatching>;
type Error = PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
PyMatching {
inner: self.into_dyn(),
}
.into_pyobject(py)
}
}
#[pymethods]
impl PyMatching {
fn __len__(&self) -> usize {
self.inner.len()
}
fn __bool__(&self) -> bool {
!self.inner.is_empty()
}
fn __iter__(&self) -> PyBorrowingIterator {
py_borrowing_iter!(self.inner.clone(), Matching<DynamicGraph>, |inner| inner
.edges_iter())
}
fn src(&self, dst: PyNodeRef) -> Option<NodeView<'static, DynamicGraph>> {
self.inner.src(dst).map(|n| n.cloned())
}
fn dst(&self, src: PyNodeRef) -> Option<NodeView<'static, DynamicGraph>> {
self.inner.dst(src).map(|n| n.cloned())
}
fn edges(&self) -> Edges<'static, DynamicGraph> {
self.inner.edges()
}
fn edge_for_src(&self, src: PyNodeRef) -> Option<EdgeView<DynamicGraph>> {
self.inner.edge_for_src(src).map(|e| e.cloned())
}
fn edge_for_dst(&self, dst: PyNodeRef) -> Option<EdgeView<DynamicGraph>> {
self.inner.edge_for_dst(dst).map(|e| e.cloned())
}
fn __contains__(&self, edge: (PyNodeRef, PyNodeRef)) -> bool {
self.inner.contains(edge.0, edge.1)
}
fn __repr__(&self) -> String {
self.inner.repr()
}
}
impl<'graph, G: GraphViewOps<'graph>> Repr for Matching<G> {
fn repr(&self) -> String {
format!("{self}")
}
}