1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
/// Generating a temporary set view of a Rust's set. This view allows random access at O(1) cost.
///
/// # Placeholder
///
/// * structname: name of the module that will contains the mapview
/// * module: name of the python module that will contains this struct
/// * derivetrait: optional, list of traits to derive for the struct
/// * itemview: the item view type (a pyo3 class) -- expect to have a constructor `new(&item)`
/// * item: the item type (rust struct)
///
/// # Example
///
/// # TODO: add example
#[macro_export]
macro_rules! pyset {
($structname:ident (module = $module:literal, item = $item:ty as $itemview:ty $(, derive = ($( $derivetrait:ident ),*) )? )) => {
pub mod $structname {
use kgdata::pyo3helper::unsafe_update_view_lifetime_signature;
use pyo3::prelude::*;
#[pyclass(module = $module, name = "SetView")]
pub struct SetView(pub &'static hashbrown::HashSet<$item>);
#[pyclass]
pub struct IterView(pub hashbrown::hash_set::Iter<'static, $item>);
impl SetView {
pub fn new(lst: &hashbrown::HashSet<$item>) -> Self {
Self(unsafe_update_view_lifetime_signature(lst))
}
}
#[pymethods]
impl SetView {
fn __iter__(&self) -> IterView {
IterView(self.0.iter())
}
fn __len__(&self) -> usize {
self.0.len()
}
fn __contains__(&self, item: $itemview) -> bool {
self.0.contains(item.0)
}
}
#[pymethods]
impl IterView {
pub fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
slf
}
pub fn __next__(&mut self) -> Option<$itemview> {
if let Some(v) = self.0.next() {
Some(<$itemview>::new(v))
} else {
None
}
}
}
}
};
}