1pub trait Collection: 'static {
6 type Item: 'static;
8 type Guard: WatcherGuard;
10
11 fn get(&self, index: usize) -> Option<Self::Item>;
13 fn len(&self) -> usize;
15
16 fn is_empty(&self) -> bool {
18 self.len() == 0
19 }
20
21 fn watch(
25 &self,
26 range: impl RangeBounds<usize>,
27 watcher: impl for<'a> Fn(Context<&'a [Self::Item]>) + 'static, ) -> Self::Guard;
29}
30
31use core::ops::{Bound, RangeBounds};
32
33use alloc::{boxed::Box, rc::Rc, vec::Vec};
34
35use crate::watcher::{BoxWatcherGuard, Context, WatcherGuard};
36
37impl<T: Clone + 'static> Collection for Vec<T> {
38 type Item = T;
39 type Guard = ();
40
41 fn get(&self, index: usize) -> Option<Self::Item> {
42 self.as_slice().get(index).cloned()
43 }
44 fn len(&self) -> usize {
45 <[T]>::len(self)
46 }
47 fn watch(
48 &self,
49 _range: impl RangeBounds<usize>,
50 _watcher: impl for<'a> Fn(Context<&'a [Self::Item]>) + 'static,
51 ) -> Self::Guard {
52 }
54}
55
56impl<T: Clone + 'static> Collection for &'static [T] {
57 type Item = T;
58 type Guard = ();
59
60 fn get(&self, index: usize) -> Option<Self::Item> {
61 (*self).get(index).cloned()
62 }
63 fn len(&self) -> usize {
64 <[T]>::len(self)
65 }
66 fn watch(
67 &self,
68 _range: impl RangeBounds<usize>,
69 _watcher: impl for<'a> Fn(Context<&'a [Self::Item]>) + 'static,
70 ) -> Self::Guard {
71 }
73}
74
75impl<T: Clone + 'static, const N: usize> Collection for [T; N] {
76 type Item = T;
77 type Guard = ();
78
79 fn get(&self, index: usize) -> Option<Self::Item> {
80 self.as_slice().get(index).cloned()
81 }
82 fn len(&self) -> usize {
83 N
84 }
85 fn watch(
86 &self,
87 _range: impl RangeBounds<usize>,
88 _watcher: impl for<'a> Fn(Context<&'a [Self::Item]>) + 'static,
89 ) -> Self::Guard {
90 }
91}
92
93impl<T: Clone + 'static> Collection for alloc::rc::Rc<[T]> {
94 type Item = T;
95 type Guard = ();
96
97 fn get(&self, index: usize) -> Option<Self::Item> {
98 self.as_ref().get(index).cloned()
99 }
100 fn len(&self) -> usize {
101 self.as_ref().len()
102 }
103 fn watch(
104 &self,
105 _range: impl RangeBounds<usize>,
106 _watcher: impl for<'a> Fn(Context<&'a [Self::Item]>) + 'static,
107 ) -> Self::Guard {
108 }
109}
110
111impl<C> Collection for Box<C>
112where
113 C: Collection,
114{
115 type Item = C::Item;
116 type Guard = C::Guard;
117
118 fn get(&self, index: usize) -> Option<Self::Item> {
119 (**self).get(index)
120 }
121 fn len(&self) -> usize {
122 (**self).len()
123 }
124 fn watch(
125 &self,
126 range: impl RangeBounds<usize>,
127 watcher: impl for<'a> Fn(Context<&'a [Self::Item]>) + 'static,
128 ) -> Self::Guard {
129 (**self).watch(range, watcher)
130 }
131}
132
133impl<C> Collection for Rc<C>
134where
135 C: Collection,
136{
137 type Item = C::Item;
138 type Guard = C::Guard;
139
140 fn get(&self, index: usize) -> Option<Self::Item> {
141 (**self).get(index)
142 }
143 fn len(&self) -> usize {
144 (**self).len()
145 }
146 fn watch(
147 &self,
148 range: impl RangeBounds<usize>,
149 watcher: impl for<'a> Fn(Context<&'a [Self::Item]>) + 'static,
150 ) -> Self::Guard {
151 (**self).watch(range, watcher)
152 }
153}
154
155pub struct AnyCollection<T> {
161 inner: Box<dyn AnyCollectionImpl<Output = T>>,
162}
163
164impl<T> core::fmt::Debug for AnyCollection<T> {
165 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
166 f.debug_struct("AnyCollection").finish()
167 }
168}
169
170pub type BoxCollectionWatcher<T> = Box<dyn for<'a> Fn(Context<&'a [T]>) + 'static>;
172
173trait AnyCollectionImpl {
175 type Output;
176 fn get(&self, index: usize) -> Option<Self::Output>;
177 fn len(&self) -> usize;
178 fn is_empty(&self) -> bool;
179 fn watch(
180 &self,
181 range: (Bound<usize>, Bound<usize>),
182 watcher: BoxCollectionWatcher<Self::Output>,
183 ) -> BoxWatcherGuard;
184}
185
186impl<T> AnyCollectionImpl for T
187where
188 T: Collection,
189{
190 type Output = T::Item;
191 fn get(&self, index: usize) -> Option<Self::Output> {
192 <T as Collection>::get(self, index)
193 }
194
195 fn len(&self) -> usize {
196 <T as Collection>::len(self)
197 }
198
199 fn is_empty(&self) -> bool {
200 <T as Collection>::is_empty(self)
201 }
202
203 fn watch(
204 &self,
205 range: (Bound<usize>, Bound<usize>),
206 watcher: Box<dyn for<'a> Fn(Context<&'a [Self::Output]>) + 'static>,
207 ) -> BoxWatcherGuard {
208 Box::new(<T as Collection>::watch(self, range, watcher))
209 }
210}
211
212impl<T> AnyCollection<T> {
213 pub fn new<C>(collection: C) -> Self
215 where
216 C: Collection<Item = T>,
217 {
218 Self {
219 inner: Box::new(collection),
220 }
221 }
222
223 #[must_use]
228 pub fn get(&self, index: usize) -> Option<T> {
229 self.inner.get(index)
230 }
231
232 #[must_use]
234 pub fn len(&self) -> usize {
235 self.inner.len()
236 }
237
238 #[must_use]
240 pub fn is_empty(&self) -> bool {
241 self.inner.is_empty()
242 }
243
244 pub fn watch(
249 &self,
250 range: impl RangeBounds<usize>,
251 watcher: impl for<'a> Fn(Context<&'a [T]>) + 'static,
252 ) -> BoxWatcherGuard {
253 let start_bound = match range.start_bound() {
254 Bound::Included(&n) => Bound::Included(n),
255 Bound::Excluded(&n) => Bound::Excluded(n),
256 Bound::Unbounded => Bound::Unbounded,
257 };
258 let end_bound = match range.end_bound() {
259 Bound::Included(&n) => Bound::Included(n),
260 Bound::Excluded(&n) => Bound::Excluded(n),
261 Bound::Unbounded => Bound::Unbounded,
262 };
263
264 self.inner
265 .watch((start_bound, end_bound), Box::new(watcher))
266 }
267}