Fully implement PureQueue
This commit is contained in:
parent
608ff1a3d5
commit
7184ddb9b0
3 changed files with 56 additions and 11 deletions
|
@ -8,12 +8,12 @@ pub struct PyItem(Py<PyAny>);
|
|||
|
||||
impl PyItem {
|
||||
/// Creates a new instance
|
||||
fn new(item: Py<PyAny>) -> Self {
|
||||
pub fn new(item: Py<PyAny>) -> Self {
|
||||
PyItem(item)
|
||||
}
|
||||
|
||||
/// Retrieves the internal data
|
||||
fn item(self) -> Py<PyAny> {
|
||||
pub fn data(self) -> Py<PyAny> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/// A "paired" priority queue that links some data to a priority and supports duplicates, but not arbitrary deletions or weight updates
|
||||
use crate::backing::{
|
||||
containers::Pair,
|
||||
pure::{BinaryHeap, PureBacking},
|
||||
|
@ -14,6 +13,7 @@ pub struct PairedQueue {
|
|||
backing: Box<dyn PureBacking<Pair<Py<PyAny>, f64>>>,
|
||||
}
|
||||
|
||||
/// A "paired" priority queue that links some data to a priority and supports duplicates, but not arbitrary deletions or priority updates
|
||||
#[pymethods]
|
||||
impl PairedQueue {
|
||||
/// Enables generic typing
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use pyo3::{prelude::*, types::PyType};
|
||||
use pyo3::{
|
||||
exceptions::{PyIndexError, PyStopIteration, PyTypeError},
|
||||
prelude::*,
|
||||
types::PyType,
|
||||
};
|
||||
|
||||
use crate::backing::{
|
||||
containers::PyItem,
|
||||
|
@ -10,23 +14,64 @@ pub struct PureQueue {
|
|||
backing: Box<dyn PureBacking<PyItem>>,
|
||||
}
|
||||
|
||||
/// A "pure" priority queue just contains the priorities without any linked data, and does not support arbitrary deletions or priority updates
|
||||
#[pymethods]
|
||||
impl PureQueue {
|
||||
/// Enables generic typing
|
||||
#[classmethod]
|
||||
fn __class_getitem__(cls_: Bound<'_, PyType>, _key: Py<PyAny>) -> Bound<'_, PyType> {
|
||||
cls_
|
||||
}
|
||||
|
||||
#[new]
|
||||
#[pyo3(signature = (items=None))]
|
||||
fn new(items: Option<Py<PyAny>>) -> PyResult<Self> {
|
||||
if let Some(py_object) = items {
|
||||
todo!()
|
||||
Python::with_gil(|py| {
|
||||
if let Ok(vec) = py_object.extract::<Vec<Py<PyAny>>>(py) {
|
||||
Ok(Self {
|
||||
backing: Box::new(BinaryHeap::from_iter(vec.into_iter().map(PyItem::new))),
|
||||
})
|
||||
} else {
|
||||
Err(PyErr::new::<PyTypeError, _>("Items was not a sequence"))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Ok(Self {
|
||||
backing: Box::new(BinaryHeap::new()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn insert(mut self_: PyRefMut<'_, Self>, item: Py<PyAny>) {
|
||||
self_.backing.add(PyItem::new(item));
|
||||
}
|
||||
|
||||
// Below methods are identical to PairedQueue
|
||||
// Normally I'd try to solve using a trait with default implementations but that doesn't seem to play nice with #[pymethods]
|
||||
// (Although I shouldn't rule it out)
|
||||
|
||||
/// Enables generic typing
|
||||
#[classmethod]
|
||||
fn __class_getitem__(cls_: Bound<'_, PyType>, _key: Py<PyAny>) -> Bound<'_, PyType> {
|
||||
cls_
|
||||
}
|
||||
|
||||
fn __len__(self_: PyRef<'_, Self>) -> usize {
|
||||
self_.backing.len()
|
||||
}
|
||||
|
||||
fn __iter__(self_: PyRef<'_, Self>) -> PyRef<'_, Self> {
|
||||
self_
|
||||
}
|
||||
|
||||
fn __next__(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
||||
if let Some(item) = self_.backing.pop() {
|
||||
Ok(item.data())
|
||||
} else {
|
||||
Err(PyErr::new::<PyStopIteration, _>(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn pop(mut self_: PyRefMut<'_, Self>) -> PyResult<Py<PyAny>> {
|
||||
if let Some(item) = self_.backing.pop() {
|
||||
Ok(item.data())
|
||||
} else {
|
||||
Err(PyErr::new::<PyIndexError, _>(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue