-use std::rc::Rc;
-use std::cell::{Ref, RefMut, RefCell};
+use std::cell::{Ref, RefCell, RefMut};
use std::ops::Range;
use std::ops::{Deref, DerefMut};
+use std::rc::Rc;
use derivative::Derivative;
use slab::Slab;
+use yew::html::IntoEventCallback;
use yew::prelude::*;
use yew::virtual_dom::Key;
-use yew::html::IntoEventCallback;
-use crate::props::{FilterFn, IntoSorterFn, IntoFilterFn, SorterFn, ExtractKeyFn, ExtractPrimaryKey};
-use crate::state::{optional_rc_ptr_eq, DataStore, DataNode, DataNodeDerefGuard};
+use crate::props::{
+ ExtractKeyFn, ExtractPrimaryKey, FilterFn, IntoFilterFn, IntoSorterFn, SorterFn,
+};
+use crate::state::{optional_rc_ptr_eq, DataNode, DataNodeDerefGuard, DataStore};
/// Hook to use a [Store] with functional components.
///
/// events which trigger a redraw.
#[hook]
pub fn use_store<F: FnOnce() -> Store<T>, T: 'static>(init_fn: F) -> Store<T> {
-
let redraw = use_state(|| 0);
let store = use_state(init_fn);
/// a simply `PartialEq` would always return true. Please register a
/// listener to get notified about changes.
#[derive(Derivative)]
-#[derivative(Clone(bound=""), PartialEq(bound=""))]
+#[derivative(Clone(bound = ""), PartialEq(bound = ""))]
pub struct Store<T: 'static> {
// Allow to store one StoreObserver here (for convenience)
- #[derivative(PartialEq(compare_with="optional_rc_ptr_eq"))]
+ #[derivative(PartialEq(compare_with = "optional_rc_ptr_eq"))]
on_change: Option<Rc<StoreObserver<T>>>,
- #[derivative(PartialEq(compare_with="Rc::ptr_eq"))]
+ #[derivative(PartialEq(compare_with = "Rc::ptr_eq"))]
inner: Rc<RefCell<StoreState<T>>>,
}
}
impl<T: ExtractPrimaryKey + 'static> Store<T> {
-
/// Creates a new instance for types implementing [ExtractPrimaryKey].
///
/// Use [Self::with_extract_key] for types which does not
}
impl<T: 'static> Store<T> {
-
/// Creates a new instance with the specifies extract key function.
pub fn with_extract_key(extract_key: impl Into<ExtractKeyFn<T>>) -> Self {
Self {
/// This is usually called by [Self::on_change], which stores the
/// observer inside the [Store] object.
pub fn add_listener(&self, cb: impl Into<Callback<()>>) -> StoreObserver<T> {
- let key = self.inner.borrow_mut()
- .add_listener(cb.into());
- StoreObserver { key, inner: self.inner.clone() }
+ let key = self.inner.borrow_mut().add_listener(cb.into());
+ StoreObserver {
+ key,
+ inner: self.inner.clone(),
+ }
}
/// Set the sorter function.
pub fn data_len(&self) -> usize {
self.inner.borrow().data.len()
- } fn lookup_filtered_record_key(&self, cursor: usize) -> Option<Key> {
+ }
+ fn lookup_filtered_record_key(&self, cursor: usize) -> Option<Key> {
let mut state = self.inner.borrow_mut();
state.update_filtered_data();
state.lookup_filtered_record_key(cursor)
pub fn filtered_data<'a>(
&'a self,
- ) -> Box<dyn Iterator<Item=(usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
+ ) -> Box<dyn Iterator<Item = (usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
self.inner.borrow_mut().update_filtered_data();
Box::new(StoreIterator {
range: None,
pos: 0,
state: self.inner.borrow(),
- })
+ })
}
pub fn filtered_data_range<'a>(
&'a self,
range: Range<usize>,
- ) -> Box<dyn Iterator<Item=(usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
+ ) -> Box<dyn Iterator<Item = (usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
self.inner.borrow_mut().update_filtered_data();
Box::new(StoreIterator {
pos: range.start,
}
#[doc(hidden)]
-pub struct StoreNodeRef<'a, T>{
+pub struct StoreNodeRef<'a, T> {
state: Ref<'a, StoreState<T>>,
node_id: usize,
}
let guard: Box<dyn Deref<Target = T>> = Box::new(data);
DataNodeDerefGuard { guard: guard }
}
- fn level(&self) -> usize { 0 }
- fn is_leaf(&self) -> bool { true }
- fn is_root(&self) -> bool { false }
- fn expanded(&self) -> bool { false }
- fn parent(&self) -> Option<Box<dyn DataNode<T> + '_>> { None }
+ fn level(&self) -> usize {
+ 0
+ }
+ fn is_leaf(&self) -> bool {
+ true
+ }
+ fn is_root(&self) -> bool {
+ false
+ }
+ fn expanded(&self) -> bool {
+ false
+ }
+ fn parent(&self) -> Option<Box<dyn DataNode<T> + '_>> {
+ None
+ }
fn key(&self) -> Key {
let record = &self.state.data[self.node_id];
self.state.extract_key(record)
}
fn add_listener(&self, cb: impl Into<Callback<()>>) -> Self::Observer {
- let key = self.inner.borrow_mut()
- .add_listener(cb.into());
- StoreObserver { key, inner: self.inner.clone() }
+ let key = self.inner.borrow_mut().add_listener(cb.into());
+ StoreObserver {
+ key,
+ inner: self.inner.clone(),
+ }
}
fn set_data(&self, data: Self::Collection) {
self.filtered_data_len()
}
- fn filtered_data<'a>(&'a self) -> Box<dyn Iterator<Item=(usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
+ fn filtered_data<'a>(
+ &'a self,
+ ) -> Box<dyn Iterator<Item = (usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
self.filtered_data()
}
fn filtered_data_range<'a>(
&'a self,
range: Range<usize>,
- ) -> Box<dyn Iterator<Item=(usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
+ ) -> Box<dyn Iterator<Item = (usize, Box<dyn DataNode<T> + 'a>)> + 'a> {
self.filtered_data_range(range)
}
}
}
impl<T: 'static> StoreState<T> {
-
fn new(extract_key: ExtractKeyFn<T>) -> Self {
Self {
data: Vec::new(),
}
fn update_filtered_data(&mut self) {
- self.filtered_data = self.data.iter().enumerate()
+ self.filtered_data = self
+ .data
+ .iter()
+ .enumerate()
.filter(|(_, record)| match &self.filter {
Some(filter) => filter.apply(record), // fixme: remove fiter record_num param
None => true,
.collect();
if let Some(sorter) = &self.sorter {
- self.filtered_data.sort_by(|a, b| {
- sorter.cmp(&self.data[*a], &self.data[*b])
- });
+ self.filtered_data
+ .sort_by(|a, b| sorter.cmp(&self.data[*a], &self.data[*b]));
}
}
}
fn filtered_record_pos(&self, key: &Key) -> Option<usize> {
- self.filtered_data.iter()
+ self.filtered_data
+ .iter()
.position(|n| key == &self.extract_key(&self.data[*n]))
}
/// Find a record position by its key.
pub fn record_pos(&self, key: &Key) -> Option<usize> {
- self.data.iter().position(|record| key == &self.extract_key(record))
+ self.data
+ .iter()
+ .position(|record| key == &self.extract_key(record))
}
/// Find a record by its key.
range: Option<Range<usize>>,
}
-impl <'a, T: 'static> Iterator for StoreIterator<'a, T> where Self: 'a {
+impl<'a, T: 'static> Iterator for StoreIterator<'a, T>
+where
+ Self: 'a,
+{
type Item = (usize, Box<dyn DataNode<T> + 'a>);
fn next(&mut self) -> Option<Self::Item> {
self.pos += 1;
let node_id = self.state.filtered_data[pos];
- let node = Box::new(StoreNodeRef { state: Ref::clone(&self.state), node_id });
+ let node = Box::new(StoreNodeRef {
+ state: Ref::clone(&self.state),
+ node_id,
+ });
Some((pos, node))
}