leptos_struct_table/
loaded_rows.rs1use std::ops::{Index, Range};
2
3#[derive(Clone)]
4pub enum RowState<T: Clone> {
5 Placeholder,
7 Loading,
9 Loaded(T),
11 Error(String),
13}
14
15impl<T: Clone> std::fmt::Debug for RowState<T> {
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 match self {
18 RowState::Placeholder => write!(f, "Placeholder"),
19 RowState::Loading => write!(f, "Loading"),
20 RowState::Loaded(_) => write!(f, "Loaded"),
21 RowState::Error(e) => write!(f, "Error({})", e),
22 }
23 }
24}
25
26pub struct LoadedRows<T: Clone> {
29 rows: Vec<RowState<T>>,
30}
31
32impl<T: Clone> LoadedRows<T> {
33 pub fn new() -> Self {
34 Self { rows: vec![] }
35 }
36
37 #[inline]
38 pub fn len(&self) -> usize {
39 self.rows.len()
40 }
41
42 #[inline]
43 pub fn resize(&mut self, len: usize) {
44 self.rows.resize(len, RowState::Placeholder);
45 }
46
47 pub fn write_loading(&mut self, range: Range<usize>) {
48 if range.end > self.rows.len() {
49 self.rows.resize(range.end, RowState::Placeholder);
50 }
51
52 for row in &mut self.rows[range] {
53 *row = RowState::Loading;
54 }
55 }
56
57 pub fn write_loaded(
58 &mut self,
59 loading_result: Result<(Vec<T>, Range<usize>), String>,
60 missing_range: Range<usize>,
61 ) {
62 match loading_result {
63 Ok((rows, range)) => {
64 if range.end > self.rows.len() {
65 self.rows.resize(range.end, RowState::Placeholder);
66 }
67
68 for (self_row, loaded_row) in self.rows[range].iter_mut().zip(rows) {
69 *self_row = RowState::Loaded(loaded_row);
70 }
71 }
72 Err(error) => {
73 let range = missing_range.start..missing_range.end.min(self.rows.len());
74 if range.start >= range.end {
75 return;
76 }
77
78 for row in &mut self.rows[range] {
79 *row = RowState::Error(error.clone());
80 }
81 }
82 }
83 }
84
85 #[inline]
86 pub fn missing_range(&self, range: Range<usize>) -> Option<Range<usize>> {
87 let do_load_predicate = |row| matches!(row, &RowState::Placeholder);
88
89 let slice = &self.rows[range.clone()];
90
91 let start = slice.iter().position(do_load_predicate)?;
92 let end = slice.iter().rposition(do_load_predicate)?;
93
94 let start = start + range.start;
95 let end = end + range.start + 1;
96
97 Some(start..end)
98 }
99
100 #[inline]
101 pub fn clear(&mut self) {
102 self.rows.fill(RowState::Placeholder);
103 }
104}
105
106impl<T: Clone> Index<Range<usize>> for LoadedRows<T> {
107 type Output = [RowState<T>];
108
109 #[inline]
110 fn index(&self, index: Range<usize>) -> &Self::Output {
111 &self.rows[index]
112 }
113}
114
115impl<T: Clone> Index<usize> for LoadedRows<T> {
116 type Output = RowState<T>;
117
118 #[inline]
119 fn index(&self, index: usize) -> &Self::Output {
120 &self.rows[index]
121 }
122}