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}