1use super::*;
7
8#[cfg(test)]
9#[derive(Default)]
10struct TestView {
11 changed_rows: RefCell<Vec<usize>>,
15 added_rows: RefCell<Vec<(usize, usize)>>,
16 removed_rows: RefCell<Vec<(usize, usize)>>,
17 reset: RefCell<usize>,
18}
19
20#[cfg(test)]
21impl TestView {
22 fn clear(&self) {
23 self.changed_rows.borrow_mut().clear();
24 self.added_rows.borrow_mut().clear();
25 self.removed_rows.borrow_mut().clear();
26 }
27}
28
29#[cfg(test)]
30impl ModelChangeListener for TestView {
31 fn row_changed(self: Pin<&Self>, row: usize) {
32 self.changed_rows.borrow_mut().push(row);
33 }
34
35 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
36 self.added_rows.borrow_mut().push((index, count));
37 }
38
39 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
40 self.removed_rows.borrow_mut().push((index, count));
41 }
42 fn reset(self: Pin<&Self>) {
43 *self.reset.borrow_mut() += 1;
44 }
45}
46
47#[cfg(test)]
48struct ModelChecker<Data: PartialEq + core::fmt::Debug + 'static> {
49 model: Rc<dyn Model<Data = Data>>,
50 rows_copy: RefCell<Vec<Data>>,
51}
52
53#[cfg(test)]
54impl<Data: PartialEq + core::fmt::Debug + 'static> ModelChangeListener for ModelChecker<Data> {
55 fn row_changed(self: Pin<&Self>, row: usize) {
56 self.rows_copy.borrow_mut()[row] = self.model.row_data(row).unwrap();
57 }
58
59 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
60 let mut copy = self.rows_copy.borrow_mut();
61 for row in index..index + count {
62 copy.insert(row, self.model.row_data(row).unwrap());
63 }
64 }
65
66 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
67 self.rows_copy.borrow_mut().drain(index..index + count);
68 }
69 fn reset(self: Pin<&Self>) {
70 *self.rows_copy.borrow_mut() = ModelRc::from(self.model.clone()).iter().collect()
71 }
72}
73
74#[cfg(test)]
75impl<Data: PartialEq + core::fmt::Debug + 'static> ModelChecker<Data> {
76 pub fn new(
77 model: Rc<impl Model<Data = Data> + 'static>,
78 ) -> Pin<Box<ModelChangeListenerContainer<Self>>> {
79 let s = Self { rows_copy: RefCell::new(model.iter().collect()), model: model.clone() };
80 let s = Box::pin(ModelChangeListenerContainer::new(s));
81 model.model_tracker().attach_peer(s.as_ref().model_peer());
82 s
83 }
84
85 #[track_caller]
86 pub fn check(&self) {
87 assert_eq!(
88 *self.rows_copy.borrow(),
89 ModelRc::from(self.model.clone()).iter().collect::<Vec<_>>()
90 );
91 }
92}
93
94#[cfg(test)]
95impl<Data: PartialEq + core::fmt::Debug + 'static> Drop for ModelChecker<Data> {
96 fn drop(&mut self) {
97 self.check();
98 }
99}
100
101pub struct MapModel<M, F> {
184 wrapped_model: M,
185 map_function: F,
186}
187
188impl<M, F, T, U> Model for MapModel<M, F>
189where
190 M: 'static,
191 F: 'static,
192 F: Fn(T) -> U,
193 M: Model<Data = T>,
194{
195 type Data = U;
196
197 fn row_count(&self) -> usize {
198 self.wrapped_model.row_count()
199 }
200
201 fn row_data(&self, row: usize) -> Option<Self::Data> {
202 self.wrapped_model.row_data(row).map(|x| (self.map_function)(x))
203 }
204
205 fn model_tracker(&self) -> &dyn ModelTracker {
206 self.wrapped_model.model_tracker()
207 }
208
209 fn as_any(&self) -> &dyn core::any::Any {
210 self
211 }
212}
213
214impl<M, F, T, U> MapModel<M, F>
215where
216 M: 'static,
217 F: 'static,
218 F: Fn(T) -> U,
219 M: Model<Data = T>,
220{
221 pub fn new(wrapped_model: M, map_function: F) -> Self {
224 Self { wrapped_model, map_function }
225 }
226
227 pub fn source_model(&self) -> &M {
229 &self.wrapped_model
230 }
231}
232
233#[test]
234fn test_map_model() {
235 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3]));
236 let map = MapModel::new(wrapped_rc.clone(), |x| x.to_string());
237
238 wrapped_rc.set_row_data(2, 42);
239 wrapped_rc.push(4);
240
241 assert_eq!(map.row_data(2).unwrap(), "42");
242 assert_eq!(map.row_data(3).unwrap(), "4");
243 assert_eq!(map.row_data(1).unwrap(), "2");
244}
245
246struct FilterModelInner<M, F>
247where
248 M: Model + 'static,
249 F: Fn(&M::Data) -> bool + 'static,
250{
251 wrapped_model: M,
252 filter_function: F,
253 mapping: RefCell<Vec<usize>>,
255 notify: ModelNotify,
256}
257
258impl<M, F> FilterModelInner<M, F>
259where
260 M: Model + 'static,
261 F: Fn(&M::Data) -> bool + 'static,
262{
263 fn build_mapping_vec(&self) {
264 let mut mapping = self.mapping.borrow_mut();
265 *mapping = self
266 .wrapped_model
267 .iter()
268 .enumerate()
269 .filter_map(|(i, e)| (self.filter_function)(&e).then_some(i))
270 .collect();
271 }
272}
273
274impl<M, F> ModelChangeListener for FilterModelInner<M, F>
275where
276 M: Model + 'static,
277 F: Fn(&M::Data) -> bool + 'static,
278{
279 fn row_changed(self: Pin<&Self>, row: usize) {
280 let mut mapping = self.mapping.borrow_mut();
281
282 let (index, is_contained) = match mapping.binary_search(&row) {
283 Ok(index) => (index, true),
284 Err(index) => (index, false),
285 };
286
287 let should_be_contained =
288 (self.filter_function)(&self.wrapped_model.row_data(row).unwrap());
289
290 if is_contained && should_be_contained {
291 drop(mapping);
292 self.notify.row_changed(index);
293 } else if !is_contained && should_be_contained {
294 mapping.insert(index, row);
295 drop(mapping);
296 self.notify.row_added(index, 1);
297 } else if is_contained && !should_be_contained {
298 mapping.remove(index);
299 drop(mapping);
300 self.notify.row_removed(index, 1);
301 }
302 }
303
304 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
305 if count == 0 {
306 return;
307 }
308
309 let insertion: Vec<usize> = self
310 .wrapped_model
311 .iter()
312 .enumerate()
313 .skip(index)
314 .take(count)
315 .filter_map(|(i, e)| (self.filter_function)(&e).then_some(i))
316 .collect();
317
318 let mut mapping = self.mapping.borrow_mut();
319 let insertion_point = mapping.binary_search(&index).unwrap_or_else(|ip| ip);
320 mapping[insertion_point..].iter_mut().for_each(|i| *i += count);
321
322 if !insertion.is_empty() {
323 let insertion_len = insertion.len();
324 mapping.splice(insertion_point..insertion_point, insertion);
325
326 drop(mapping);
327 self.notify.row_added(insertion_point, insertion_len);
328 }
329 }
330
331 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
332 if count == 0 {
333 return;
334 }
335 let mut mapping = self.mapping.borrow_mut();
336
337 let start = mapping.binary_search(&index).unwrap_or_else(|s| s);
338 let end = mapping.binary_search(&(index + count)).unwrap_or_else(|e| e);
339 let range = start..end;
340
341 mapping[end..].iter_mut().for_each(|i| *i -= count);
342
343 if !range.is_empty() {
344 mapping.drain(range.clone());
345 drop(mapping);
346 self.notify.row_removed(start, range.len());
347 }
348 }
349
350 fn reset(self: Pin<&Self>) {
351 self.build_mapping_vec();
352 self.notify.reset();
353 }
354}
355
356pub struct FilterModel<M, F>(Pin<Box<ModelChangeListenerContainer<FilterModelInner<M, F>>>>)
417where
418 M: Model + 'static,
419 F: Fn(&M::Data) -> bool + 'static;
420
421impl<M, F> FilterModel<M, F>
422where
423 M: Model + 'static,
424 F: Fn(&M::Data) -> bool + 'static,
425{
426 pub fn new(wrapped_model: M, filter_function: F) -> Self {
429 let filter_model_inner = FilterModelInner {
430 wrapped_model,
431 filter_function,
432 mapping: RefCell::new(Vec::new()),
433 notify: Default::default(),
434 };
435
436 filter_model_inner.build_mapping_vec();
437
438 let container = Box::pin(ModelChangeListenerContainer::new(filter_model_inner));
439
440 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
441
442 Self(container)
443 }
444
445 pub fn reset(&self) {
448 self.0.as_ref().get().reset();
449 }
450
451 pub fn unfiltered_row(&self, filtered_row: usize) -> usize {
453 self.0.mapping.borrow()[filtered_row]
454 }
455
456 pub fn source_model(&self) -> &M {
458 &self.0.as_ref().get().get_ref().wrapped_model
459 }
460}
461
462impl<M, F> Model for FilterModel<M, F>
463where
464 M: Model + 'static,
465 F: Fn(&M::Data) -> bool + 'static,
466{
467 type Data = M::Data;
468
469 fn row_count(&self) -> usize {
470 self.0.mapping.borrow().len()
471 }
472
473 fn row_data(&self, row: usize) -> Option<Self::Data> {
474 self.0
475 .mapping
476 .borrow()
477 .get(row)
478 .and_then(|&wrapped_row| self.0.wrapped_model.row_data(wrapped_row))
479 }
480
481 fn set_row_data(&self, row: usize, data: Self::Data) {
482 let wrapped_row = self.0.mapping.borrow()[row];
483 self.0.wrapped_model.set_row_data(wrapped_row, data);
484 }
485
486 fn model_tracker(&self) -> &dyn ModelTracker {
487 &self.0.notify
488 }
489
490 fn as_any(&self) -> &dyn core::any::Any {
491 self
492 }
493}
494
495#[test]
496fn test_filter_model() {
497 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4, 5, 6]));
498 let filter = Rc::new(FilterModel::new(wrapped_rc.clone(), |x| x % 2 == 0));
499
500 let _checker = ModelChecker::new(filter.clone());
501
502 assert_eq!(filter.row_data(0).unwrap(), 2);
503 assert_eq!(filter.row_data(1).unwrap(), 4);
504 assert_eq!(filter.row_data(2).unwrap(), 6);
505 assert_eq!(filter.row_count(), 3);
506
507 wrapped_rc.remove(1);
508 assert_eq!(filter.row_data(0).unwrap(), 4);
509 assert_eq!(filter.row_data(1).unwrap(), 6);
510 assert_eq!(filter.row_count(), 2);
511
512 wrapped_rc.push(8);
513 wrapped_rc.push(7);
514 assert_eq!(filter.row_data(0).unwrap(), 4);
515 assert_eq!(filter.row_data(1).unwrap(), 6);
516 assert_eq!(filter.row_data(2).unwrap(), 8);
517 assert_eq!(filter.row_count(), 3);
518
519 wrapped_rc.set_row_data(1, 2);
520 assert_eq!(filter.row_data(0).unwrap(), 2);
521 assert_eq!(filter.row_data(1).unwrap(), 4);
522 assert_eq!(filter.row_data(2).unwrap(), 6);
523 assert_eq!(filter.row_data(3).unwrap(), 8);
524 assert_eq!(filter.row_count(), 4);
525
526 wrapped_rc.insert(2, 12);
527 assert_eq!(filter.row_data(0).unwrap(), 2);
528 assert_eq!(filter.row_data(1).unwrap(), 12);
529 assert_eq!(filter.row_data(2).unwrap(), 4);
530 assert_eq!(filter.row_data(3).unwrap(), 6);
531 assert_eq!(filter.row_data(4).unwrap(), 8);
532 assert_eq!(filter.row_count(), 5);
533}
534
535#[test]
536fn test_filter_model_source_model() {
537 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
538 let model = Rc::new(FilterModel::new(wrapped_rc.clone(), |x| x % 2 == 0));
539
540 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
541 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
542
543 let _checker = ModelChecker::new(model.clone());
544
545 model.source_model().push(5);
546 model.source_model().push(6);
547
548 let expected = &[2, 4, 6];
549 assert_eq!(model.row_count(), expected.len());
550 for (i, v) in expected.iter().enumerate() {
551 assert_eq!(model.row_data(i), Some(*v), "Expected {} at index {}", v, i);
552 }
553}
554
555pub trait SortHelper<D> {
556 fn cmp(&mut self, lhs: &D, rhs: &D) -> core::cmp::Ordering;
557}
558
559pub struct AscendingSortHelper;
560
561impl<D> SortHelper<D> for AscendingSortHelper
562where
563 D: core::cmp::Ord,
564{
565 fn cmp(&mut self, lhs: &D, rhs: &D) -> core::cmp::Ordering {
566 lhs.cmp(rhs)
567 }
568}
569
570impl<F, D> SortHelper<D> for F
571where
572 F: FnMut(&D, &D) -> core::cmp::Ordering + 'static,
573{
574 fn cmp(&mut self, lhs: &D, rhs: &D) -> core::cmp::Ordering {
575 (self)(lhs, rhs)
576 }
577}
578
579struct SortModelInner<M, S>
580where
581 M: Model + 'static,
582 S: SortHelper<M::Data> + 'static,
583{
584 wrapped_model: M,
585 sort_helper: RefCell<S>,
586 mapping: RefCell<Vec<usize>>,
588 notify: ModelNotify,
589 sorted_rows_dirty: Cell<bool>,
590}
591
592impl<M, S> SortModelInner<M, S>
593where
594 M: Model + 'static,
595 S: SortHelper<M::Data>,
596{
597 fn build_mapping_vec(&self) {
598 if !self.sorted_rows_dirty.get() {
599 return;
600 }
601
602 let mut mapping = self.mapping.borrow_mut();
603
604 mapping.clear();
605 mapping.extend(0..self.wrapped_model.row_count());
606 mapping.sort_by(|lhs, rhs| {
607 self.sort_helper.borrow_mut().cmp(
608 &self.wrapped_model.row_data(*lhs).unwrap(),
609 &self.wrapped_model.row_data(*rhs).unwrap(),
610 )
611 });
612
613 self.sorted_rows_dirty.set(false);
614 }
615}
616
617impl<M, S> ModelChangeListener for SortModelInner<M, S>
618where
619 M: Model + 'static,
620 S: SortHelper<M::Data> + 'static,
621{
622 fn row_changed(self: Pin<&Self>, row: usize) {
623 if self.sorted_rows_dirty.get() {
624 self.reset();
625 return;
626 }
627
628 let mut mapping = self.mapping.borrow_mut();
629 let removed_index = mapping.iter().position(|r| *r == row).unwrap();
630 mapping.remove(removed_index);
631
632 let changed_data = self.wrapped_model.row_data(row).unwrap();
633 let insertion_index = mapping.partition_point(|existing_row| {
634 self.sort_helper
635 .borrow_mut()
636 .cmp(&self.wrapped_model.row_data(*existing_row).unwrap(), &changed_data)
637 == core::cmp::Ordering::Less
638 });
639
640 mapping.insert(insertion_index, row);
641
642 drop(mapping);
643
644 if insertion_index == removed_index {
645 self.notify.row_changed(removed_index);
646 } else {
647 self.notify.row_removed(removed_index, 1);
648 self.notify.row_added(insertion_index, 1);
649 }
650 }
651
652 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
653 if count == 0 {
654 return;
655 }
656
657 if self.sorted_rows_dirty.get() {
658 self.reset();
659 return;
660 }
661
662 for row in self.mapping.borrow_mut().iter_mut() {
664 if *row >= index {
665 *row += count;
666 }
667 }
668
669 for row in index..(index + count) {
670 let added_data = self.wrapped_model.row_data(row).unwrap();
671 let insertion_index = self.mapping.borrow().partition_point(|existing_row| {
672 self.sort_helper
673 .borrow_mut()
674 .cmp(&self.wrapped_model.row_data(*existing_row).unwrap(), &added_data)
675 == core::cmp::Ordering::Less
676 });
677
678 self.mapping.borrow_mut().insert(insertion_index, row);
679 self.notify.row_added(insertion_index, 1)
680 }
681 }
682
683 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
684 if count == 0 {
685 return;
686 }
687
688 if self.sorted_rows_dirty.get() {
689 self.reset();
690 return;
691 }
692
693 let mut removed_rows = Vec::new();
694
695 let mut i = 0;
696
697 loop {
698 if i >= self.mapping.borrow().len() {
699 break;
700 }
701
702 let sort_index = self.mapping.borrow()[i];
703
704 if sort_index >= index {
705 if sort_index < index + count {
706 removed_rows.push(i);
707 self.mapping.borrow_mut().remove(i);
708 continue;
709 } else {
710 self.mapping.borrow_mut()[i] -= count;
711 }
712 }
713
714 i += 1;
715 }
716
717 for removed_row in removed_rows {
718 self.notify.row_removed(removed_row, 1);
719 }
720 }
721
722 fn reset(self: Pin<&Self>) {
723 self.sorted_rows_dirty.set(true);
724 self.notify.reset();
725 }
726}
727
728pub struct SortModel<M, F>(Pin<Box<ModelChangeListenerContainer<SortModelInner<M, F>>>>)
822where
823 M: Model + 'static,
824 F: SortHelper<M::Data> + 'static;
825
826impl<M, F> SortModel<M, F>
827where
828 M: Model + 'static,
829 F: FnMut(&M::Data, &M::Data) -> core::cmp::Ordering + 'static,
830{
831 pub fn new(wrapped_model: M, sort_function: F) -> Self
834 where
835 F: FnMut(&M::Data, &M::Data) -> core::cmp::Ordering + 'static,
836 {
837 let sorted_model_inner = SortModelInner {
838 wrapped_model,
839 sort_helper: RefCell::new(sort_function),
840 mapping: RefCell::new(Vec::new()),
841 notify: Default::default(),
842 sorted_rows_dirty: Cell::new(true),
843 };
844
845 let container = Box::pin(ModelChangeListenerContainer::new(sorted_model_inner));
846
847 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
848
849 Self(container)
850 }
851
852 pub fn source_model(&self) -> &M {
854 &self.0.as_ref().get().get_ref().wrapped_model
855 }
856}
857
858impl<M> SortModel<M, AscendingSortHelper>
859where
860 M: Model + 'static,
861 M::Data: core::cmp::Ord,
862{
863 pub fn new_ascending(wrapped_model: M) -> Self
866 where
867 M::Data: core::cmp::Ord,
868 {
869 let sorted_model_inner = SortModelInner {
870 wrapped_model,
871 sort_helper: RefCell::new(AscendingSortHelper),
872 mapping: RefCell::new(Vec::new()),
873 notify: Default::default(),
874 sorted_rows_dirty: Cell::new(true),
875 };
876
877 let container = Box::pin(ModelChangeListenerContainer::new(sorted_model_inner));
878
879 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
880
881 Self(container)
882 }
883
884 pub fn reset(&self) {
887 self.0.as_ref().get().reset();
888 }
889
890 pub fn unsorted_row(&self, sorted_row: usize) -> usize {
892 self.0.build_mapping_vec();
893 self.0.mapping.borrow()[sorted_row]
894 }
895}
896
897impl<M, S> Model for SortModel<M, S>
898where
899 M: Model + 'static,
900 S: SortHelper<M::Data>,
901{
902 type Data = M::Data;
903
904 fn row_count(&self) -> usize {
905 self.0.wrapped_model.row_count()
906 }
907
908 fn row_data(&self, row: usize) -> Option<Self::Data> {
909 self.0.build_mapping_vec();
910
911 self.0
912 .mapping
913 .borrow()
914 .get(row)
915 .and_then(|&wrapped_row| self.0.wrapped_model.row_data(wrapped_row))
916 }
917
918 fn set_row_data(&self, row: usize, data: Self::Data) {
919 let wrapped_row = self.0.mapping.borrow()[row];
920 self.0.wrapped_model.set_row_data(wrapped_row, data);
921 }
922
923 fn model_tracker(&self) -> &dyn ModelTracker {
924 &self.0.notify
925 }
926
927 fn as_any(&self) -> &dyn core::any::Any {
928 self
929 }
930}
931
932#[cfg(test)]
933mod sort_tests {
934 use super::*;
935
936 #[test]
937 fn test_sorted_model_insert() {
938 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
939 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
940
941 let _checker = ModelChecker::new(sorted_model.clone());
942
943 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
944 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
945
946 assert_eq!(sorted_model.row_count(), 4);
947 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
948 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
949 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
950 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
951
952 wrapped_rc.insert(0, 10);
953
954 assert_eq!(observer.added_rows.borrow().len(), 1);
955 assert!(observer.added_rows.borrow().eq(&[(4, 1)]));
956 assert!(observer.changed_rows.borrow().is_empty());
957 assert!(observer.removed_rows.borrow().is_empty());
958 assert_eq!(*observer.reset.borrow(), 0);
959 observer.clear();
960
961 assert_eq!(sorted_model.row_count(), 5);
962 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
963 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
964 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
965 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
966 assert_eq!(sorted_model.row_data(4).unwrap(), 10);
967 }
968
969 #[test]
970 fn test_sorted_model_remove() {
971 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
972 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
973
974 let _checker = ModelChecker::new(sorted_model.clone());
975
976 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
977 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
978
979 assert_eq!(sorted_model.row_count(), 4);
980 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
981 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
982 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
983 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
984
985 wrapped_rc.remove(1);
987
988 assert!(observer.added_rows.borrow().is_empty());
989 assert!(observer.changed_rows.borrow().is_empty());
990 assert_eq!(observer.removed_rows.borrow().len(), 1);
991 assert!(observer.removed_rows.borrow().eq(&[(3, 1)]));
992 assert_eq!(*observer.reset.borrow(), 0);
993 observer.clear();
994
995 assert_eq!(sorted_model.row_count(), 3);
996 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
997 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
998 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
999 }
1000
1001 #[test]
1002 fn test_sorted_model_changed() {
1003 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1004 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1005
1006 let _checker = ModelChecker::new(sorted_model.clone());
1007
1008 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1009 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1010
1011 assert_eq!(sorted_model.row_count(), 4);
1012 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1013 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1014 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1015 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1016
1017 wrapped_rc.set_row_data(1, 10);
1019
1020 assert!(observer.added_rows.borrow().is_empty());
1021 assert_eq!(observer.changed_rows.borrow().len(), 1);
1022 assert_eq!(*observer.changed_rows.borrow().first().unwrap(), 3);
1023 assert!(observer.removed_rows.borrow().is_empty());
1024 assert_eq!(*observer.reset.borrow(), 0);
1025 observer.clear();
1026
1027 assert_eq!(sorted_model.row_count(), 4);
1028 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1029 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1030 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1031 assert_eq!(sorted_model.row_data(3).unwrap(), 10);
1032
1033 wrapped_rc.set_row_data(1, 0);
1035
1036 assert_eq!(observer.added_rows.borrow().len(), 1);
1037 assert!(observer.added_rows.borrow().first().unwrap().eq(&(0, 1)));
1038 assert!(observer.changed_rows.borrow().is_empty());
1039 assert_eq!(observer.removed_rows.borrow().len(), 1);
1040 assert!(observer.removed_rows.borrow().first().unwrap().eq(&(3, 1)));
1041 assert_eq!(*observer.reset.borrow(), 0);
1042 observer.clear();
1043
1044 assert_eq!(sorted_model.row_count(), 4);
1045 assert_eq!(sorted_model.row_data(0).unwrap(), 0);
1046 assert_eq!(sorted_model.row_data(1).unwrap(), 1);
1047 assert_eq!(sorted_model.row_data(2).unwrap(), 2);
1048 assert_eq!(sorted_model.row_data(3).unwrap(), 3);
1049 }
1050
1051 #[test]
1052 fn test_sorted_model_source_model() {
1053 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1054 let model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1055 let _checker = ModelChecker::new(model.clone());
1056
1057 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1058 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1059
1060 model.source_model().push(6);
1061 model.source_model().push(5);
1062
1063 let expected = &[1, 2, 3, 4, 5, 6];
1064 assert_eq!(model.row_count(), expected.len());
1065 for (i, v) in expected.iter().enumerate() {
1066 assert_eq!(model.row_data(i), Some(*v), "Expected {} at index {}", v, i);
1067 }
1068 }
1069}
1070
1071pub struct ReverseModel<M>(Pin<Box<ModelChangeListenerContainer<ReverseModelInner<M>>>>)
1135where
1136 M: Model + 'static;
1137
1138struct ReverseModelInner<M>
1139where
1140 M: Model + 'static,
1141{
1142 wrapped_model: M,
1143 notify: ModelNotify,
1144}
1145
1146impl<M> ModelChangeListener for ReverseModelInner<M>
1147where
1148 M: Model + 'static,
1149{
1150 fn row_changed(self: Pin<&Self>, row: usize) {
1151 self.notify.row_changed(self.wrapped_model.row_count() - 1 - row);
1152 }
1153
1154 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
1155 let row_count = self.wrapped_model.row_count();
1156 let old_row_count = row_count - count;
1157 let index = old_row_count - index;
1158 self.notify.row_added(index, count);
1159 }
1160
1161 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
1162 let row_count = self.wrapped_model.row_count();
1163 self.notify.row_removed(row_count - index, count);
1164 }
1165
1166 fn reset(self: Pin<&Self>) {
1167 self.notify.reset()
1168 }
1169}
1170
1171impl<M> ReverseModel<M>
1172where
1173 M: Model + 'static,
1174{
1175 pub fn new(wrapped_model: M) -> Self {
1178 let inner = ReverseModelInner { wrapped_model, notify: Default::default() };
1179 let container = Box::pin(ModelChangeListenerContainer::new(inner));
1180 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
1181 Self(container)
1182 }
1183
1184 pub fn source_model(&self) -> &M {
1186 &self.0.as_ref().get().get_ref().wrapped_model
1187 }
1188}
1189
1190impl<M> Model for ReverseModel<M>
1191where
1192 M: Model + 'static,
1193{
1194 type Data = M::Data;
1195
1196 fn row_count(&self) -> usize {
1197 self.0.wrapped_model.row_count()
1198 }
1199
1200 fn row_data(&self, row: usize) -> Option<Self::Data> {
1201 let count = self.0.wrapped_model.row_count();
1202 self.0.wrapped_model.row_data(count.checked_sub(row + 1)?)
1203 }
1204 fn set_row_data(&self, row: usize, data: Self::Data) {
1205 let count = self.0.as_ref().wrapped_model.row_count();
1206 self.0.wrapped_model.set_row_data(count - row - 1, data);
1207 }
1208
1209 fn model_tracker(&self) -> &dyn ModelTracker {
1210 &self.0.notify
1211 }
1212
1213 fn as_any(&self) -> &dyn core::any::Any {
1214 self
1215 }
1216}
1217
1218#[cfg(test)]
1219mod reversed_tests {
1220 use super::*;
1221
1222 #[track_caller]
1223 fn check_content(model: &ReverseModel<Rc<VecModel<i32>>>, expected: &[i32]) {
1224 assert_eq!(model.row_count(), expected.len());
1225 for (i, v) in expected.iter().enumerate() {
1226 assert_eq!(model.row_data(i), Some(*v), "Expected {} at index {}", v, i);
1227 }
1228 }
1229
1230 #[test]
1231 fn test_reversed_model() {
1232 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1233 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1234 let _checker = ModelChecker::new(model.clone());
1235
1236 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1237 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1238
1239 check_content(&model, &[4, 3, 2, 1]);
1240 }
1241
1242 #[test]
1243 fn test_reversed_model_insert() {
1244 for (idx, mapped_idx) in [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)] {
1245 println!("Inserting at {} expecting mapped to {}", idx, mapped_idx);
1246 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1247 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1248 let _checker = ModelChecker::new(model.clone());
1249
1250 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1251 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1252
1253 wrapped_rc.insert(idx, 10);
1254
1255 assert_eq!(observer.added_rows.borrow().len(), 1);
1256 assert!(
1257 observer.added_rows.borrow().eq(&[(mapped_idx, 1)]),
1258 "Added rows: {:?}",
1259 observer.added_rows.borrow()
1260 );
1261 assert!(observer.changed_rows.borrow().is_empty());
1262 assert!(observer.removed_rows.borrow().is_empty());
1263 assert_eq!(*observer.reset.borrow(), 0);
1264 assert_eq!(model.row_data(mapped_idx), Some(10));
1265 }
1266 }
1267
1268 #[test]
1269 fn test_reversed_model_remove() {
1270 for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
1271 println!("Removing at {} expecting mapped to {}", idx, mapped_idx);
1272 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1273 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1274 let _checker = ModelChecker::new(model.clone());
1275
1276 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1277 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1278
1279 wrapped_rc.remove(idx);
1280
1281 assert_eq!(observer.removed_rows.borrow().len(), 1);
1282 assert!(
1283 observer.removed_rows.borrow().eq(&[(mapped_idx, 1)]),
1284 "Remove rows: {:?}",
1285 observer.removed_rows.borrow()
1286 );
1287 assert!(observer.added_rows.borrow().is_empty());
1288 assert!(observer.changed_rows.borrow().is_empty());
1289 assert_eq!(*observer.reset.borrow(), 0);
1290 }
1291 }
1292
1293 #[test]
1294 fn test_reversed_model_changed() {
1295 for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
1296 println!("Changing at {} expecting mapped to {}", idx, mapped_idx);
1297 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1298 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1299 let _checker = ModelChecker::new(model.clone());
1300
1301 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1302 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1303
1304 wrapped_rc.set_row_data(idx, 10);
1305
1306 assert_eq!(observer.changed_rows.borrow().len(), 1);
1307 assert!(
1308 observer.changed_rows.borrow().eq(&[mapped_idx]),
1309 "Changed rows: {:?}",
1310 observer.changed_rows.borrow()
1311 );
1312 assert!(observer.added_rows.borrow().is_empty());
1313 assert!(observer.removed_rows.borrow().is_empty());
1314 assert_eq!(*observer.reset.borrow(), 0);
1315 assert_eq!(model.row_data(mapped_idx), Some(10));
1316 }
1317 }
1318
1319 #[test]
1320 fn test_reversed_model_source_model() {
1321 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1322 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1323 let _checker = ModelChecker::new(model.clone());
1324
1325 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1326 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1327
1328 model.source_model().push(5);
1329
1330 check_content(&model, &[5, 4, 3, 2, 1]);
1331 }
1332}
1333
1334#[test]
1335fn test_long_chain_integrity() {
1336 let origin_model = Rc::new(VecModel::from((0..100).collect::<Vec<_>>()));
1337 let checker1 = ModelChecker::new(origin_model.clone());
1338 let fizzbuzz = Rc::new(MapModel::new(origin_model.clone(), |number| {
1339 if (number % 3) == 0 && (number % 5) == 0 {
1340 "FizzBuzz".to_owned()
1341 } else if (number % 3) == 0 {
1342 "Fizz".to_owned()
1343 } else if (number % 5) == 0 {
1344 "Buzz".to_owned()
1345 } else {
1346 number.to_string()
1347 }
1348 }));
1349 let checker2 = ModelChecker::new(fizzbuzz.clone());
1350 let filter = Rc::new(FilterModel::new(fizzbuzz, |s| s != "FizzBuzz"));
1351 let checker3 = ModelChecker::new(filter.clone());
1352 let reverse = Rc::new(ReverseModel::new(filter));
1353 let checker4 = ModelChecker::new(reverse.clone());
1354 let sorted = Rc::new(SortModel::new_ascending(reverse));
1355 let checker5 = ModelChecker::new(sorted.clone());
1356 let filter2 = Rc::new(FilterModel::new(sorted, |s| s != "Fizz"));
1357 let checker6 = ModelChecker::new(filter2.clone());
1358
1359 let check_all = || {
1360 checker1.check();
1361 checker2.check();
1362 checker3.check();
1363 checker4.check();
1364 checker5.check();
1365 checker6.check();
1366 };
1367
1368 origin_model.extend(50..150);
1369 check_all();
1370 origin_model.insert(8, 1000);
1371 check_all();
1372 origin_model.remove(9);
1373 check_all();
1374 origin_model.remove(10);
1375 origin_model.remove(11);
1376 origin_model.set_row_data(55, 10001);
1377 check_all();
1378 origin_model.set_row_data(58, 10002);
1379 origin_model.set_row_data(59, 10003);
1380 origin_model.remove(28);
1381 origin_model.remove(29);
1382 origin_model.insert(100, 8888);
1383 origin_model.remove(30);
1384 origin_model.set_row_data(60, 10004);
1385 origin_model.remove(130);
1386 origin_model.set_row_data(61, 10005);
1387 origin_model.remove(131);
1388 check_all();
1389 origin_model.remove(12);
1390 origin_model.remove(13);
1391 origin_model.remove(14);
1392 origin_model.set_row_data(62, 10006);
1393 origin_model.set_row_data(63, 10007);
1394 origin_model.set_row_data(64, 10008);
1395 origin_model.set_row_data(65, 10009);
1396 check_all();
1397
1398 trait RemoveRange {
1400 fn remove_range(&self, range: core::ops::Range<usize>);
1401 }
1402 impl<T> RemoveRange for VecModel<T> {
1403 fn remove_range(&self, range: core::ops::Range<usize>) {
1404 self.array.borrow_mut().drain(range.clone());
1405 self.notify.row_removed(range.start, range.len())
1406 }
1407 }
1408
1409 origin_model.remove_range(25..110);
1410 check_all();
1411
1412 origin_model.extend(900..910);
1413 origin_model.set_row_data(45, 44444);
1414 origin_model.remove_range(10..30);
1415 origin_model.insert(45, 3000);
1416 origin_model.insert(45, 3001);
1417 origin_model.insert(45, 3002);
1418 origin_model.insert(45, 3003);
1419 origin_model.insert(45, 3004);
1420 origin_model.insert(45, 3006);
1421 origin_model.insert(45, 3007);
1422 check_all();
1423}