dioxus_lazy/
use_lazy.rs

1use crate::lazy::Values;
2use dioxus::prelude::*;
3use std::{cmp::Ordering, collections::VecDeque, ops::Range};
4
5pub fn use_lazy<F, V, I>(make_value: F) -> UseLazy<F, V>
6where
7    F: FnMut(Range<usize>, bool) -> I + 'static,
8    I: IntoIterator<Item = V>,
9{
10    let values = use_signal(|| VecDeque::new());
11    let range = use_signal(|| 0..0);
12
13    UseLazy {
14        make_value: CopyValue::new(make_value),
15        values,
16        range,
17    }
18}
19
20pub struct UseLazy<F: 'static, V: 'static> {
21    pub values: Signal<VecDeque<V>>,
22    make_value: CopyValue<F>,
23    range: Signal<Range<usize>>,
24}
25
26impl<F, V, I> Values for UseLazy<F, V>
27where
28    F: FnMut(Range<usize>, bool) -> I + 'static,
29    I: IntoIterator<Item = V>,
30{
31    type Value = V;
32
33    fn values(&self) -> Signal<VecDeque<Self::Value>> {
34        self.values
35    }
36
37    fn set(&mut self, range: Range<usize>) {
38        let mut last = self.range.write();
39        let mut values = self.values;
40
41        match range.start.cmp(&last.start) {
42            Ordering::Less => {
43                let mut rows_ref = values.write();
44                let values = (self.make_value).write()(range.start..last.start, true);
45                for value in values.into_iter() {
46                    rows_ref.push_front(value);
47                }
48            }
49            Ordering::Greater => {
50                let mut rows_ref = values.write();
51                for _ in 0..range.start - last.start {
52                    rows_ref.pop_front();
53                }
54            }
55            Ordering::Equal => {}
56        }
57
58        if range.start != range.end {
59            match range.end.cmp(&last.end) {
60                Ordering::Greater => {
61                    let mut rows_ref = values.write();
62                    let values = (self.make_value).write()(last.end..range.end, false);
63                    for value in values.into_iter() {
64                        rows_ref.push_back(value);
65                    }
66                }
67                Ordering::Less => {
68                    let mut rows_ref = values.write();
69                    for _ in 0..last.end - range.end {
70                        rows_ref.pop_back();
71                    }
72                }
73                Ordering::Equal => {}
74            }
75        }
76
77        *last = range;
78    }
79
80    fn refresh(&mut self) {
81        let last = self.range.read();
82        let mut values_ref = self.values.write();
83        values_ref.clear();
84
85        let values = (self.make_value).write()(last.start..last.end, false);
86        for value in values.into_iter() {
87            values_ref.push_back(value);
88        }
89    }
90}
91
92impl<F, V> Clone for UseLazy<F, V> {
93    fn clone(&self) -> Self {
94        *self
95    }
96}
97
98impl<F, V> Copy for UseLazy<F, V> {}
99
100impl<F, V> PartialEq for UseLazy<F, V> {
101    fn eq(&self, other: &Self) -> bool {
102        self.values == other.values
103    }
104}