patternfly_yew/components/table/model/
table.rs

1use super::{TableDataModel, TableModelEntry};
2use crate::prelude::ExpansionState;
3use std::cell::RefCell;
4use std::collections::HashMap;
5use std::hash::Hash;
6use std::marker::PhantomData;
7use std::rc::Rc;
8use yew::virtual_dom::Key;
9
10/// A [`super::TableModel`] based on a [`TableDataModel`] plus additional state.
11pub struct StateModel<C, M>
12where
13    C: Clone + Eq + 'static,
14    M: TableDataModel<C>,
15{
16    _marker: PhantomData<C>,
17    model: M,
18    state: Rc<RefCell<HashMap<M::Key, ExpansionState<C>>>>,
19}
20
21impl<C, M> StateModel<C, M>
22where
23    C: Clone + Eq + 'static,
24    M: TableDataModel<C>,
25{
26    pub fn new(model: M, state: Rc<RefCell<HashMap<M::Key, ExpansionState<C>>>>) -> Self {
27        Self {
28            model,
29            state,
30            _marker: Default::default(),
31        }
32    }
33}
34
35impl<C, M> PartialEq for StateModel<C, M>
36where
37    C: Clone + Eq + 'static,
38    M: PartialEq + TableDataModel<C>,
39    M::Key: Hash,
40{
41    fn eq(&self, other: &Self) -> bool {
42        self.state == other.state && self.model == other.model
43    }
44}
45
46impl<C, M> super::TableModel<C> for StateModel<C, M>
47where
48    C: Clone + Eq + 'static,
49    M: TableDataModel<C> + 'static,
50    M::Key: Hash,
51{
52    type Iterator<'i> = StateModelIter<'i, Self::Key, Self::Item, C>;
53    type Item = M::Item;
54    type Key = M::Key;
55
56    fn len(&self) -> usize {
57        self.model.len()
58    }
59
60    fn is_empty(&self) -> bool {
61        self.model.is_empty()
62    }
63
64    fn iter(&self) -> Self::Iterator<'_> {
65        let state = self.state.borrow().clone();
66        StateModelIter::new(self.model.iter().map(move |(key, value)| {
67            let expansion = state.get(&key).cloned();
68            TableModelEntry {
69                key,
70                value,
71                expansion,
72            }
73        }))
74    }
75}
76
77pub struct StateModelIter<'i, K, V, C>(Box<dyn Iterator<Item = TableModelEntry<'i, V, K, C>> + 'i>)
78where
79    K: Into<Key>,
80    C: Clone + Eq;
81
82impl<'i, K, V, C> StateModelIter<'i, K, V, C>
83where
84    K: Into<Key>,
85    C: Clone + Eq,
86{
87    pub fn new<I>(iter: I) -> Self
88    where
89        I: Iterator<Item = TableModelEntry<'i, V, K, C>> + 'i,
90    {
91        Self(Box::new(iter))
92    }
93}
94
95impl<'i, K, V, C> Iterator for StateModelIter<'i, K, V, C>
96where
97    K: Into<Key>,
98    C: Clone + Eq,
99{
100    type Item = TableModelEntry<'i, V, K, C>;
101
102    fn next(&mut self) -> Option<Self::Item> {
103        self.0.next()
104    }
105}