1use super::*;
8
9#[cfg(test)]
10mod tests_helper {
11 use super::*;
12
13 #[derive(Default)]
14 pub struct TestView {
15 pub changed_rows: RefCell<Vec<usize>>,
19 pub added_rows: RefCell<Vec<(usize, usize)>>,
20 pub removed_rows: RefCell<Vec<(usize, usize)>>,
21 pub reset: RefCell<usize>,
22 }
23
24 impl TestView {
25 pub fn clear(&self) {
26 self.changed_rows.borrow_mut().clear();
27 self.added_rows.borrow_mut().clear();
28 self.removed_rows.borrow_mut().clear();
29 }
30 }
31
32 impl ModelChangeListener for TestView {
33 fn row_changed(self: Pin<&Self>, row: usize) {
34 self.changed_rows.borrow_mut().push(row);
35 }
36
37 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
38 self.added_rows.borrow_mut().push((index, count));
39 }
40
41 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
42 self.removed_rows.borrow_mut().push((index, count));
43 }
44 fn reset(self: Pin<&Self>) {
45 *self.reset.borrow_mut() += 1;
46 }
47 }
48
49 pub struct ModelChecker<Data: PartialEq + core::fmt::Debug + 'static> {
50 pub model: Rc<dyn Model<Data = Data>>,
51 pub rows_copy: RefCell<Vec<Data>>,
52 }
53
54 impl<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 impl<Data: PartialEq + core::fmt::Debug + 'static> ModelChecker<Data> {
75 pub fn new(model: Rc<impl Model<Data = Data> + 'static>) -> ModelChangeListenerBox<Self> {
76 let s = Self { rows_copy: RefCell::new(model.iter().collect()), model: model.clone() };
77 let s = ModelChangeListenerBox::new(s);
78 model.model_tracker().attach_peer(s.as_ref().model_peer());
79 s
80 }
81
82 #[track_caller]
83 pub fn check(&self) {
84 assert_eq!(
85 *self.rows_copy.borrow(),
86 ModelRc::from(self.model.clone()).iter().collect::<Vec<_>>()
87 );
88 }
89 }
90
91 impl<Data: PartialEq + core::fmt::Debug + 'static> Drop for ModelChecker<Data> {
92 fn drop(&mut self) {
93 self.check();
94 }
95 }
96
97 #[derive(Default)]
98 pub struct BrokenModel<T> {
99 pub data: RefCell<Vec<Option<T>>>,
100 pub notify: ModelNotify,
101 }
102
103 #[cfg(test)]
104 impl<T: Clone> Model for BrokenModel<T> {
105 type Data = T;
106
107 fn row_count(&self) -> usize {
108 self.data.borrow().len()
109 }
110
111 fn row_data(&self, row: usize) -> Option<Self::Data> {
112 self.data.borrow().get(row).and_then(|x| x.clone())
113 }
114
115 fn set_row_data(&self, row: usize, data: Self::Data) {
116 self.data.borrow_mut()[row] = Some(data);
117 self.notify.row_changed(row);
118 }
119
120 fn model_tracker(&self) -> &dyn ModelTracker {
121 &self.notify
122 }
123 }
124
125 impl<T> BrokenModel<T> {
126 pub fn new(data: Vec<Option<T>>) -> Rc<Self> {
127 Rc::new(Self { data: RefCell::new(data), notify: Default::default() })
128 }
129 }
130}
131
132pub struct MapModel<M, F> {
215 wrapped_model: M,
216 map_function: F,
217}
218
219impl<M, F, T, U> Model for MapModel<M, F>
220where
221 M: 'static,
222 F: 'static,
223 F: Fn(T) -> U,
224 M: Model<Data = T>,
225{
226 type Data = U;
227
228 fn row_count(&self) -> usize {
229 self.wrapped_model.row_count()
230 }
231
232 fn row_data(&self, row: usize) -> Option<Self::Data> {
233 self.wrapped_model.row_data(row).map(|x| (self.map_function)(x))
234 }
235
236 fn model_tracker(&self) -> &dyn ModelTracker {
237 self.wrapped_model.model_tracker()
238 }
239
240 fn as_any(&self) -> &dyn core::any::Any {
241 self
242 }
243}
244
245impl<M, F, T, U> MapModel<M, F>
246where
247 M: 'static,
248 F: 'static,
249 F: Fn(T) -> U,
250 M: Model<Data = T>,
251{
252 pub fn new(wrapped_model: M, map_function: F) -> Self {
255 Self { wrapped_model, map_function }
256 }
257
258 pub fn source_model(&self) -> &M {
260 &self.wrapped_model
261 }
262}
263
264#[test]
265fn test_map_model() {
266 use alloc::string::ToString;
267 let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3]));
268 let map = MapModel::new(wrapped_rc.clone(), |x| x.to_string());
269
270 wrapped_rc.set_row_data(2, 42);
271 wrapped_rc.push(4);
272
273 assert_eq!(map.row_data(2).unwrap(), "42");
274 assert_eq!(map.row_data(3).unwrap(), "4");
275 assert_eq!(map.row_data(1).unwrap(), "2");
276}
277
278struct FilterModelInner<M, F>
279where
280 M: Model + 'static,
281 F: Fn(&M::Data) -> bool + 'static,
282{
283 wrapped_model: M,
284 filter_function: F,
285 mapping: RefCell<Vec<usize>>,
287 notify: ModelNotify,
288}
289
290impl<M, F> FilterModelInner<M, F>
291where
292 M: Model + 'static,
293 F: Fn(&M::Data) -> bool + 'static,
294{
295 fn build_mapping_vec(&self) {
296 let mut mapping = self.mapping.borrow_mut();
297 *mapping = (0..self.wrapped_model.row_count())
298 .filter_map(|i| {
299 self.wrapped_model.row_data(i).and_then(|e| (self.filter_function)(&e).then_some(i))
300 })
301 .collect();
302 }
303}
304
305impl<M, F> ModelChangeListener for FilterModelInner<M, F>
306where
307 M: Model + 'static,
308 F: Fn(&M::Data) -> bool + 'static,
309{
310 fn row_changed(self: Pin<&Self>, row: usize) {
311 let mut mapping = self.mapping.borrow_mut();
312
313 let (index, is_contained) = match mapping.binary_search(&row) {
314 Ok(index) => (index, true),
315 Err(index) => (index, false),
316 };
317
318 let should_be_contained =
319 self.wrapped_model.row_data(row).is_some_and(|data| (self.filter_function)(&data));
320
321 if is_contained && should_be_contained {
322 drop(mapping);
323 self.notify.row_changed(index);
324 } else if !is_contained && should_be_contained {
325 mapping.insert(index, row);
326 drop(mapping);
327 self.notify.row_added(index, 1);
328 } else if is_contained && !should_be_contained {
329 mapping.remove(index);
330 drop(mapping);
331 self.notify.row_removed(index, 1);
332 }
333 }
334
335 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
336 if count == 0 {
337 return;
338 }
339
340 let insertion: Vec<usize> = self
341 .wrapped_model
342 .iter()
343 .enumerate()
344 .skip(index)
345 .take(count)
346 .filter_map(|(i, e)| (self.filter_function)(&e).then_some(i))
347 .collect();
348
349 let mut mapping = self.mapping.borrow_mut();
350 let insertion_point = mapping.binary_search(&index).unwrap_or_else(|ip| ip);
351 mapping[insertion_point..].iter_mut().for_each(|i| *i += count);
352
353 if !insertion.is_empty() {
354 let insertion_len = insertion.len();
355 mapping.splice(insertion_point..insertion_point, insertion);
356
357 drop(mapping);
358 self.notify.row_added(insertion_point, insertion_len);
359 }
360 }
361
362 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
363 if count == 0 {
364 return;
365 }
366 let mut mapping = self.mapping.borrow_mut();
367
368 let start = mapping.binary_search(&index).unwrap_or_else(|s| s);
369 let end = mapping.binary_search(&(index + count)).unwrap_or_else(|e| e);
370 let range = start..end;
371
372 mapping[end..].iter_mut().for_each(|i| *i -= count);
373
374 if !range.is_empty() {
375 mapping.drain(range.clone());
376 drop(mapping);
377 self.notify.row_removed(start, range.len());
378 }
379 }
380
381 fn reset(self: Pin<&Self>) {
382 self.build_mapping_vec();
383 self.notify.reset();
384 }
385}
386
387pub struct FilterModel<M, F>(ModelChangeListenerBox<FilterModelInner<M, F>>)
448where
449 M: Model + 'static,
450 F: Fn(&M::Data) -> bool + 'static;
451
452impl<M, F> FilterModel<M, F>
453where
454 M: Model + 'static,
455 F: Fn(&M::Data) -> bool + 'static,
456{
457 pub fn new(wrapped_model: M, filter_function: F) -> Self {
460 let filter_model_inner = FilterModelInner {
461 wrapped_model,
462 filter_function,
463 mapping: RefCell::new(Vec::new()),
464 notify: Default::default(),
465 };
466
467 filter_model_inner.build_mapping_vec();
468
469 let container = ModelChangeListenerBox::new(filter_model_inner);
470
471 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
472
473 Self(container)
474 }
475
476 pub fn reset(&self) {
479 self.0.as_ref().get().reset();
480 }
481
482 pub fn unfiltered_row(&self, filtered_row: usize) -> usize {
484 self.0.mapping.borrow()[filtered_row]
485 }
486
487 pub fn source_model(&self) -> &M {
489 &self.0.as_ref().get().get_ref().wrapped_model
490 }
491}
492
493impl<M, F> Model for FilterModel<M, F>
494where
495 M: Model + 'static,
496 F: Fn(&M::Data) -> bool + 'static,
497{
498 type Data = M::Data;
499
500 fn row_count(&self) -> usize {
501 self.0.mapping.borrow().len()
502 }
503
504 fn row_data(&self, row: usize) -> Option<Self::Data> {
505 self.0
506 .mapping
507 .borrow()
508 .get(row)
509 .and_then(|&wrapped_row| self.0.wrapped_model.row_data(wrapped_row))
510 }
511
512 fn set_row_data(&self, row: usize, data: Self::Data) {
513 let wrapped_row = self.0.mapping.borrow()[row];
514 self.0.wrapped_model.set_row_data(wrapped_row, data);
515 }
516
517 fn model_tracker(&self) -> &dyn ModelTracker {
518 &self.0.notify
519 }
520
521 fn as_any(&self) -> &dyn core::any::Any {
522 self
523 }
524}
525
526#[test]
527fn test_filter_model() {
528 use tests_helper::*;
529 let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4, 5, 6]));
530 let filter = Rc::new(FilterModel::new(wrapped_rc.clone(), |x| x % 2 == 0));
531
532 let _checker = ModelChecker::new(filter.clone());
533
534 assert_eq!(filter.row_data(0).unwrap(), 2);
535 assert_eq!(filter.row_data(1).unwrap(), 4);
536 assert_eq!(filter.row_data(2).unwrap(), 6);
537 assert_eq!(filter.row_count(), 3);
538
539 wrapped_rc.remove(1);
540 assert_eq!(filter.row_data(0).unwrap(), 4);
541 assert_eq!(filter.row_data(1).unwrap(), 6);
542 assert_eq!(filter.row_count(), 2);
543
544 wrapped_rc.push(8);
545 wrapped_rc.push(7);
546 assert_eq!(filter.row_data(0).unwrap(), 4);
547 assert_eq!(filter.row_data(1).unwrap(), 6);
548 assert_eq!(filter.row_data(2).unwrap(), 8);
549 assert_eq!(filter.row_count(), 3);
550
551 wrapped_rc.set_row_data(1, 2);
552 assert_eq!(filter.row_data(0).unwrap(), 2);
553 assert_eq!(filter.row_data(1).unwrap(), 4);
554 assert_eq!(filter.row_data(2).unwrap(), 6);
555 assert_eq!(filter.row_data(3).unwrap(), 8);
556 assert_eq!(filter.row_count(), 4);
557
558 wrapped_rc.insert(2, 12);
559 assert_eq!(filter.row_data(0).unwrap(), 2);
560 assert_eq!(filter.row_data(1).unwrap(), 12);
561 assert_eq!(filter.row_data(2).unwrap(), 4);
562 assert_eq!(filter.row_data(3).unwrap(), 6);
563 assert_eq!(filter.row_data(4).unwrap(), 8);
564 assert_eq!(filter.row_count(), 5);
565}
566
567#[test]
568fn test_filter_model_source_model() {
569 use tests_helper::*;
570 let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
571 let model = Rc::new(FilterModel::new(wrapped_rc.clone(), |x| x % 2 == 0));
572
573 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
574 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
575
576 let _checker = ModelChecker::new(model.clone());
577
578 model.source_model().push(5);
579 model.source_model().push(6);
580
581 let expected = &[2, 4, 6];
582 assert_eq!(model.row_count(), expected.len());
583 for (i, v) in expected.iter().enumerate() {
584 assert_eq!(model.row_data(i), Some(*v), "Expected {v} at index {i}");
585 }
586}
587
588#[test]
589fn test_filter_model_broken_model() {
590 use tests_helper::*;
591 let wrapped_rc = BrokenModel::new(std::vec![Some(1), Some(2), None, Some(3), None, Some(4)]);
592 let model = Rc::new(FilterModel::new(wrapped_rc.clone(), |x| x % 2 == 0));
593
594 assert_eq!(model.row_count(), 2);
595 assert_eq!(model.row_data(0), Some(2));
596 assert_eq!(model.row_data(1), Some(4));
597
598 wrapped_rc.notify.row_removed(1, 2);
599 wrapped_rc.notify.row_added(1, 2);
600 wrapped_rc.data.borrow_mut()[1] = None;
601 wrapped_rc.data.borrow_mut()[2] = Some(8);
602 wrapped_rc.notify.row_changed(1);
603 wrapped_rc.notify.row_changed(2);
604
605 assert_eq!(model.row_count(), 2);
606 assert_eq!(model.row_data(0), Some(8));
607 assert_eq!(model.row_data(1), Some(4));
608}
609
610pub trait SortHelper<D> {
611 fn cmp(&mut self, lhs: &D, rhs: &D) -> core::cmp::Ordering;
612}
613
614pub struct AscendingSortHelper;
615
616impl<D> SortHelper<D> for AscendingSortHelper
617where
618 D: core::cmp::Ord,
619{
620 fn cmp(&mut self, lhs: &D, rhs: &D) -> core::cmp::Ordering {
621 lhs.cmp(rhs)
622 }
623}
624
625impl<F, D> SortHelper<D> for F
626where
627 F: FnMut(&D, &D) -> core::cmp::Ordering + 'static,
628{
629 fn cmp(&mut self, lhs: &D, rhs: &D) -> core::cmp::Ordering {
630 (self)(lhs, rhs)
631 }
632}
633
634struct SortModelInner<M, S>
635where
636 M: Model + 'static,
637 S: SortHelper<M::Data> + 'static,
638{
639 wrapped_model: M,
640 sort_helper: RefCell<S>,
641 mapping: RefCell<Vec<usize>>,
643 notify: ModelNotify,
644 sorted_rows_dirty: Cell<bool>,
645}
646
647impl<M, S> SortModelInner<M, S>
648where
649 M: Model + 'static,
650 S: SortHelper<M::Data>,
651{
652 fn build_mapping_vec(&self) {
653 if !self.sorted_rows_dirty.get() {
654 return;
655 }
656
657 let mut mapping = self.mapping.borrow_mut();
658
659 mapping.clear();
660 mapping.extend(0..self.wrapped_model.row_count());
661 mapping.sort_by(|lhs, rhs| {
662 let Some(lhs) = self.wrapped_model.row_data(*lhs) else {
663 return core::cmp::Ordering::Greater;
664 };
665 let Some(rhs) = self.wrapped_model.row_data(*rhs) else {
666 return core::cmp::Ordering::Less;
667 };
668 self.sort_helper.borrow_mut().cmp(&lhs, &rhs)
669 });
670
671 self.sorted_rows_dirty.set(false);
672 }
673}
674
675impl<M, S> ModelChangeListener for SortModelInner<M, S>
676where
677 M: Model + 'static,
678 S: SortHelper<M::Data> + 'static,
679{
680 fn row_changed(self: Pin<&Self>, row: usize) {
681 if self.sorted_rows_dirty.get() {
682 self.reset();
683 return;
684 }
685
686 let mut mapping = self.mapping.borrow_mut();
687 let removed_index = mapping.iter().position(|r| *r == row).unwrap();
688 mapping.remove(removed_index);
689
690 let insertion_index = if let Some(changed_data) = self.wrapped_model.row_data(row) {
691 mapping.partition_point(|existing_row| {
692 self.wrapped_model.row_data(*existing_row).is_some_and(|existing| {
693 self.sort_helper.borrow_mut().cmp(&existing, &changed_data)
694 == core::cmp::Ordering::Less
695 })
696 })
697 } else {
698 mapping.len()
699 };
700
701 mapping.insert(insertion_index, row);
702
703 drop(mapping);
704
705 if insertion_index == removed_index {
706 self.notify.row_changed(removed_index);
707 } else {
708 self.notify.row_removed(removed_index, 1);
709 self.notify.row_added(insertion_index, 1);
710 }
711 }
712
713 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
714 if count == 0 {
715 return;
716 }
717
718 if self.sorted_rows_dirty.get() {
719 self.reset();
720 return;
721 }
722
723 for row in self.mapping.borrow_mut().iter_mut() {
725 if *row >= index {
726 *row += count;
727 }
728 }
729
730 for row in index..(index + count) {
731 let insertion_index = if let Some(added_data) = self.wrapped_model.row_data(row) {
732 self.mapping.borrow().partition_point(|existing_row| {
733 self.wrapped_model.row_data(*existing_row).is_some_and(|existing| {
734 self.sort_helper.borrow_mut().cmp(&existing, &added_data)
735 == core::cmp::Ordering::Less
736 })
737 })
738 } else {
739 self.mapping.borrow().len()
740 };
741 self.mapping.borrow_mut().insert(insertion_index, row);
742 self.notify.row_added(insertion_index, 1)
743 }
744 }
745
746 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
747 if count == 0 {
748 return;
749 }
750
751 if self.sorted_rows_dirty.get() {
752 self.reset();
753 return;
754 }
755
756 let mut removed_rows = Vec::new();
757
758 let mut i = 0;
759
760 loop {
761 if i >= self.mapping.borrow().len() {
762 break;
763 }
764
765 let sort_index = self.mapping.borrow()[i];
766
767 if sort_index >= index {
768 if sort_index < index + count {
769 removed_rows.push(i);
770 self.mapping.borrow_mut().remove(i);
771 continue;
772 } else {
773 self.mapping.borrow_mut()[i] -= count;
774 }
775 }
776
777 i += 1;
778 }
779
780 for removed_row in removed_rows {
781 self.notify.row_removed(removed_row, 1);
782 }
783 }
784
785 fn reset(self: Pin<&Self>) {
786 self.sorted_rows_dirty.set(true);
787 self.notify.reset();
788 }
789}
790
791pub struct SortModel<M, F>(ModelChangeListenerBox<SortModelInner<M, F>>)
885where
886 M: Model + 'static,
887 F: SortHelper<M::Data> + 'static;
888
889impl<M, F> SortModel<M, F>
890where
891 M: Model + 'static,
892 F: FnMut(&M::Data, &M::Data) -> core::cmp::Ordering + 'static,
893{
894 pub fn new(wrapped_model: M, sort_function: F) -> Self
897 where
898 F: FnMut(&M::Data, &M::Data) -> core::cmp::Ordering + 'static,
899 {
900 let sorted_model_inner = SortModelInner {
901 wrapped_model,
902 sort_helper: RefCell::new(sort_function),
903 mapping: RefCell::new(Vec::new()),
904 notify: Default::default(),
905 sorted_rows_dirty: Cell::new(true),
906 };
907
908 let container = ModelChangeListenerBox::new(sorted_model_inner);
909
910 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
911
912 Self(container)
913 }
914}
915
916impl<M> SortModel<M, AscendingSortHelper>
917where
918 M: Model + 'static,
919 M::Data: core::cmp::Ord,
920{
921 pub fn new_ascending(wrapped_model: M) -> Self
924 where
925 M::Data: core::cmp::Ord,
926 {
927 let sorted_model_inner = SortModelInner {
928 wrapped_model,
929 sort_helper: RefCell::new(AscendingSortHelper),
930 mapping: RefCell::new(Vec::new()),
931 notify: Default::default(),
932 sorted_rows_dirty: Cell::new(true),
933 };
934
935 let container = ModelChangeListenerBox::new(sorted_model_inner);
936
937 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
938
939 Self(container)
940 }
941}
942
943impl<M, S> SortModel<M, S>
944where
945 M: Model + 'static,
946 S: SortHelper<M::Data>,
947{
948 pub fn source_model(&self) -> &M {
950 &self.0.as_ref().get().get_ref().wrapped_model
951 }
952
953 pub fn reset(&self) {
956 self.0.as_ref().get().reset();
957 }
958
959 pub fn unsorted_row(&self, sorted_row: usize) -> usize {
961 self.0.build_mapping_vec();
962 self.0.mapping.borrow()[sorted_row]
963 }
964}
965
966impl<M, S> Model for SortModel<M, S>
967where
968 M: Model + 'static,
969 S: SortHelper<M::Data>,
970{
971 type Data = M::Data;
972
973 fn row_count(&self) -> usize {
974 self.0.wrapped_model.row_count()
975 }
976
977 fn row_data(&self, row: usize) -> Option<Self::Data> {
978 self.0.build_mapping_vec();
979
980 self.0
981 .mapping
982 .borrow()
983 .get(row)
984 .and_then(|&wrapped_row| self.0.wrapped_model.row_data(wrapped_row))
985 }
986
987 fn set_row_data(&self, row: usize, data: Self::Data) {
988 let wrapped_row = self.0.mapping.borrow()[row];
989 self.0.wrapped_model.set_row_data(wrapped_row, data);
990 }
991
992 fn model_tracker(&self) -> &dyn ModelTracker {
993 &self.0.notify
994 }
995
996 fn as_any(&self) -> &dyn core::any::Any {
997 self
998 }
999}
1000
1001#[cfg(test)]
1002mod sort_tests {
1003 use super::*;
1004 use std::vec;
1005 use tests_helper::*;
1006
1007 #[test]
1008 fn test_sorted_model_insert() {
1009 let wrapped_rc = Rc::new(VecModel::from(std::vec![3, 4, 1, 2]));
1010 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1011
1012 let _checker = ModelChecker::new(sorted_model.clone());
1013
1014 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1015 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1016
1017 assert_eq!(sorted_model.row_count(), 4);
1018 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1019 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1020 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1021 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1022
1023 wrapped_rc.insert(0, 10);
1024
1025 assert_eq!(observer.added_rows.borrow().len(), 1);
1026 assert!(observer.added_rows.borrow().eq(&[(4, 1)]));
1027 assert!(observer.changed_rows.borrow().is_empty());
1028 assert!(observer.removed_rows.borrow().is_empty());
1029 assert_eq!(*observer.reset.borrow(), 0);
1030 observer.clear();
1031
1032 assert_eq!(sorted_model.row_count(), 5);
1033 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1034 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1035 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1036 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1037 assert_eq!(sorted_model.row_data(4).unwrap(), 10);
1038 }
1039
1040 #[test]
1041 fn test_sorted_model_remove() {
1042 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1043 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1044
1045 let _checker = ModelChecker::new(sorted_model.clone());
1046
1047 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1048 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1049
1050 assert_eq!(sorted_model.row_count(), 4);
1051 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1052 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1053 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1054 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1055
1056 wrapped_rc.remove(1);
1058
1059 assert!(observer.added_rows.borrow().is_empty());
1060 assert!(observer.changed_rows.borrow().is_empty());
1061 assert_eq!(observer.removed_rows.borrow().len(), 1);
1062 assert!(observer.removed_rows.borrow().eq(&[(3, 1)]));
1063 assert_eq!(*observer.reset.borrow(), 0);
1064 observer.clear();
1065
1066 assert_eq!(sorted_model.row_count(), 3);
1067 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1068 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1069 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1070 }
1071
1072 #[test]
1073 fn test_sorted_model_changed() {
1074 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1075 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1076
1077 let _checker = ModelChecker::new(sorted_model.clone());
1078
1079 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1080 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1081
1082 assert_eq!(sorted_model.row_count(), 4);
1083 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1084 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1085 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1086 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1087
1088 wrapped_rc.set_row_data(1, 10);
1090
1091 assert!(observer.added_rows.borrow().is_empty());
1092 assert_eq!(observer.changed_rows.borrow().len(), 1);
1093 assert_eq!(*observer.changed_rows.borrow().first().unwrap(), 3);
1094 assert!(observer.removed_rows.borrow().is_empty());
1095 assert_eq!(*observer.reset.borrow(), 0);
1096 observer.clear();
1097
1098 assert_eq!(sorted_model.row_count(), 4);
1099 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1100 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1101 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1102 assert_eq!(sorted_model.row_data(3).unwrap(), 10);
1103
1104 wrapped_rc.set_row_data(1, 0);
1106
1107 assert_eq!(observer.added_rows.borrow().len(), 1);
1108 assert!(observer.added_rows.borrow().first().unwrap().eq(&(0, 1)));
1109 assert!(observer.changed_rows.borrow().is_empty());
1110 assert_eq!(observer.removed_rows.borrow().len(), 1);
1111 assert!(observer.removed_rows.borrow().first().unwrap().eq(&(3, 1)));
1112 assert_eq!(*observer.reset.borrow(), 0);
1113 observer.clear();
1114
1115 assert_eq!(sorted_model.row_count(), 4);
1116 assert_eq!(sorted_model.row_data(0).unwrap(), 0);
1117 assert_eq!(sorted_model.row_data(1).unwrap(), 1);
1118 assert_eq!(sorted_model.row_data(2).unwrap(), 2);
1119 assert_eq!(sorted_model.row_data(3).unwrap(), 3);
1120 }
1121
1122 #[test]
1123 fn test_sorted_model_source_model() {
1124 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1125 let model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1126 let _checker = ModelChecker::new(model.clone());
1127
1128 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1129 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1130
1131 model.source_model().push(6);
1132 model.source_model().push(5);
1133
1134 let expected = &[1, 2, 3, 4, 5, 6];
1135 assert_eq!(model.row_count(), expected.len());
1136 for (i, v) in expected.iter().enumerate() {
1137 assert_eq!(model.row_data(i), Some(*v), "Expected {v} at index {i}");
1138 }
1139
1140 assert!(Rc::ptr_eq(model.source_model(), &wrapped_rc));
1141 model.reset();
1142 assert_eq!(*observer.reset.borrow(), 1);
1143 }
1144
1145 #[test]
1146 fn test_sorted_broken_model() {
1147 let wrapped_rc = BrokenModel::new(std::vec![
1148 Some("1"),
1149 Some("2"),
1150 None,
1151 Some("4"),
1152 None,
1153 Some("3"),
1154 Some("0"),
1155 Some("5")
1156 ]);
1157 let model = Rc::new(SortModel::new_ascending(wrapped_rc.clone()));
1158
1159 assert_eq!(model.row_count(), 8);
1160 assert_eq!(model.row_data(0), Some("0"));
1161 assert_eq!(model.row_data(1), Some("1"));
1162 assert_eq!(model.row_data(2), Some("2"));
1163 assert_eq!(model.row_data(3), Some("3"));
1164 assert_eq!(model.row_data(4), Some("4"));
1165 assert_eq!(model.row_data(5), Some("5"));
1166 assert_eq!(model.row_data(6), None);
1167 assert_eq!(model.row_data(7), None);
1168
1169 wrapped_rc.notify.row_removed(2, 2);
1170 wrapped_rc.notify.row_added(2, 2);
1171 wrapped_rc.data.borrow_mut()[1] = None;
1172 wrapped_rc.notify.row_changed(1);
1173 wrapped_rc.data.borrow_mut()[2] = Some("a");
1174 wrapped_rc.notify.row_changed(2);
1175
1176 assert_eq!(model.row_count(), 8);
1177 assert_eq!(model.row_data(0), Some("0"));
1178 assert_eq!(model.row_data(1), Some("1"));
1179 assert_eq!(model.row_data(2), Some("3"));
1180 assert_eq!(model.row_data(3), Some("4"));
1181 assert_eq!(model.row_data(4), Some("5"));
1182 assert_eq!(model.row_data(5), Some("a"));
1183 assert_eq!(model.row_data(6), None);
1184 assert_eq!(model.row_data(7), None);
1185
1186 assert!(Rc::ptr_eq(model.source_model(), &wrapped_rc));
1187 }
1188}
1189
1190pub struct ReverseModel<M>(ModelChangeListenerBox<ReverseModelInner<M>>)
1254where
1255 M: Model + 'static;
1256
1257struct ReverseModelInner<M>
1258where
1259 M: Model + 'static,
1260{
1261 wrapped_model: M,
1262 notify: ModelNotify,
1263}
1264
1265impl<M> ModelChangeListener for ReverseModelInner<M>
1266where
1267 M: Model + 'static,
1268{
1269 fn row_changed(self: Pin<&Self>, row: usize) {
1270 self.notify.row_changed(self.wrapped_model.row_count() - 1 - row);
1271 }
1272
1273 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
1274 let row_count = self.wrapped_model.row_count();
1275 let old_row_count = row_count - count;
1276 let index = old_row_count - index;
1277 self.notify.row_added(index, count);
1278 }
1279
1280 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
1281 let row_count = self.wrapped_model.row_count();
1282 self.notify.row_removed(row_count - index, count);
1283 }
1284
1285 fn reset(self: Pin<&Self>) {
1286 self.notify.reset()
1287 }
1288}
1289
1290impl<M> ReverseModel<M>
1291where
1292 M: Model + 'static,
1293{
1294 pub fn new(wrapped_model: M) -> Self {
1297 let inner = ReverseModelInner { wrapped_model, notify: Default::default() };
1298 let container = ModelChangeListenerBox::new(inner);
1299 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
1300 Self(container)
1301 }
1302
1303 pub fn source_model(&self) -> &M {
1305 &self.0.as_ref().get().get_ref().wrapped_model
1306 }
1307}
1308
1309impl<M> Model for ReverseModel<M>
1310where
1311 M: Model + 'static,
1312{
1313 type Data = M::Data;
1314
1315 fn row_count(&self) -> usize {
1316 self.0.wrapped_model.row_count()
1317 }
1318
1319 fn row_data(&self, row: usize) -> Option<Self::Data> {
1320 let count = self.0.wrapped_model.row_count();
1321 self.0.wrapped_model.row_data(count.checked_sub(row + 1)?)
1322 }
1323 fn set_row_data(&self, row: usize, data: Self::Data) {
1324 let count = self.0.as_ref().wrapped_model.row_count();
1325 self.0.wrapped_model.set_row_data(count - row - 1, data);
1326 }
1327
1328 fn model_tracker(&self) -> &dyn ModelTracker {
1329 &self.0.notify
1330 }
1331
1332 fn as_any(&self) -> &dyn core::any::Any {
1333 self
1334 }
1335}
1336
1337#[cfg(test)]
1338mod reversed_tests {
1339 use super::*;
1340 use std::vec;
1341 use tests_helper::*;
1342
1343 #[track_caller]
1344 fn check_content(model: &ReverseModel<Rc<VecModel<i32>>>, expected: &[i32]) {
1345 assert_eq!(model.row_count(), expected.len());
1346 for (i, v) in expected.iter().enumerate() {
1347 assert_eq!(model.row_data(i), Some(*v), "Expected {v} at index {i}");
1348 }
1349 }
1350
1351 #[test]
1352 fn test_reversed_model() {
1353 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1354 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1355 let _checker = ModelChecker::new(model.clone());
1356
1357 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1358 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1359
1360 check_content(&model, &[4, 3, 2, 1]);
1361 }
1362
1363 #[test]
1364 fn test_reversed_model_insert() {
1365 for (idx, mapped_idx) in [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)] {
1366 std::println!("Inserting at {idx} expecting mapped to {mapped_idx}");
1367 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1368 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1369 let _checker = ModelChecker::new(model.clone());
1370
1371 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1372 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1373
1374 wrapped_rc.insert(idx, 10);
1375
1376 assert_eq!(observer.added_rows.borrow().len(), 1);
1377 assert!(
1378 observer.added_rows.borrow().eq(&[(mapped_idx, 1)]),
1379 "Added rows: {:?}",
1380 observer.added_rows.borrow()
1381 );
1382 assert!(observer.changed_rows.borrow().is_empty());
1383 assert!(observer.removed_rows.borrow().is_empty());
1384 assert_eq!(*observer.reset.borrow(), 0);
1385 assert_eq!(model.row_data(mapped_idx), Some(10));
1386 }
1387 }
1388
1389 #[test]
1390 fn test_reversed_model_remove() {
1391 for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
1392 std::println!("Removing at {idx} expecting mapped to {mapped_idx}");
1393 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1394 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1395 let _checker = ModelChecker::new(model.clone());
1396
1397 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1398 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1399
1400 wrapped_rc.remove(idx);
1401
1402 assert_eq!(observer.removed_rows.borrow().len(), 1);
1403 assert!(
1404 observer.removed_rows.borrow().eq(&[(mapped_idx, 1)]),
1405 "Remove rows: {:?}",
1406 observer.removed_rows.borrow()
1407 );
1408 assert!(observer.added_rows.borrow().is_empty());
1409 assert!(observer.changed_rows.borrow().is_empty());
1410 assert_eq!(*observer.reset.borrow(), 0);
1411 }
1412 }
1413
1414 #[test]
1415 fn test_reversed_model_changed() {
1416 for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
1417 std::println!("Changing at {idx} expecting mapped to {mapped_idx}");
1418 let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
1419 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1420 let _checker = ModelChecker::new(model.clone());
1421
1422 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1423 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1424
1425 wrapped_rc.set_row_data(idx, 10);
1426
1427 assert_eq!(observer.changed_rows.borrow().len(), 1);
1428 assert!(
1429 observer.changed_rows.borrow().eq(&[mapped_idx]),
1430 "Changed rows: {:?}",
1431 observer.changed_rows.borrow()
1432 );
1433 assert!(observer.added_rows.borrow().is_empty());
1434 assert!(observer.removed_rows.borrow().is_empty());
1435 assert_eq!(*observer.reset.borrow(), 0);
1436 assert_eq!(model.row_data(mapped_idx), Some(10));
1437 }
1438 }
1439
1440 #[test]
1441 fn test_reversed_model_source_model() {
1442 let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
1443 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1444 let _checker = ModelChecker::new(model.clone());
1445
1446 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1447 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1448
1449 model.source_model().push(5);
1450
1451 check_content(&model, &[5, 4, 3, 2, 1]);
1452 }
1453
1454 #[test]
1455 fn test_reversed_broken_model() {
1456 let wrapped_rc = BrokenModel::new(std::vec![Some("1"), Some("2"), None, Some("4")]);
1457 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1458
1459 wrapped_rc.notify.row_added(1, 3);
1460
1461 assert_eq!(model.row_count(), 4);
1462 assert_eq!(model.row_data(0), Some("4"));
1463 assert_eq!(model.row_data(1), None);
1464 assert_eq!(model.row_data(2), Some("2"));
1465 assert_eq!(model.row_data(3), Some("1"));
1466 }
1467}
1468
1469#[test]
1470fn test_long_chain_integrity() {
1471 use alloc::string::ToString;
1472 use tests_helper::*;
1473 let origin_model = Rc::new(VecModel::from((0..100).collect::<Vec<_>>()));
1474 let checker1 = ModelChecker::new(origin_model.clone());
1475 let fizzbuzz = Rc::new(MapModel::new(origin_model.clone(), |number| {
1476 if (number % 3) == 0 && (number % 5) == 0 {
1477 "FizzBuzz".to_string()
1478 } else if (number % 3) == 0 {
1479 "Fizz".to_string()
1480 } else if (number % 5) == 0 {
1481 "Buzz".to_string()
1482 } else {
1483 number.to_string()
1484 }
1485 }));
1486 let checker2 = ModelChecker::new(fizzbuzz.clone());
1487 let filter = Rc::new(FilterModel::new(fizzbuzz, |s| s != "FizzBuzz"));
1488 let checker3 = ModelChecker::new(filter.clone());
1489 let reverse = Rc::new(ReverseModel::new(filter));
1490 let checker4 = ModelChecker::new(reverse.clone());
1491 let sorted = Rc::new(SortModel::new_ascending(reverse));
1492 let checker5 = ModelChecker::new(sorted.clone());
1493 let filter2 = Rc::new(FilterModel::new(sorted, |s| s != "Fizz"));
1494 let checker6 = ModelChecker::new(filter2.clone());
1495
1496 let check_all = || {
1497 checker1.check();
1498 checker2.check();
1499 checker3.check();
1500 checker4.check();
1501 checker5.check();
1502 checker6.check();
1503 };
1504
1505 origin_model.extend(50..150);
1506 check_all();
1507 origin_model.insert(8, 1000);
1508 check_all();
1509 origin_model.remove(9);
1510 check_all();
1511 origin_model.remove(10);
1512 origin_model.remove(11);
1513 origin_model.set_row_data(55, 10001);
1514 check_all();
1515 origin_model.set_row_data(58, 10002);
1516 origin_model.set_row_data(59, 10003);
1517 origin_model.remove(28);
1518 origin_model.remove(29);
1519 origin_model.insert(100, 8888);
1520 origin_model.remove(30);
1521 origin_model.set_row_data(60, 10004);
1522 origin_model.remove(130);
1523 origin_model.set_row_data(61, 10005);
1524 origin_model.remove(131);
1525 check_all();
1526 origin_model.remove(12);
1527 origin_model.remove(13);
1528 origin_model.remove(14);
1529 origin_model.set_row_data(62, 10006);
1530 origin_model.set_row_data(63, 10007);
1531 origin_model.set_row_data(64, 10008);
1532 origin_model.set_row_data(65, 10009);
1533 check_all();
1534
1535 trait RemoveRange {
1537 fn remove_range(&self, range: core::ops::Range<usize>);
1538 }
1539 impl<T> RemoveRange for VecModel<T> {
1540 fn remove_range(&self, range: core::ops::Range<usize>) {
1541 self.array.borrow_mut().drain(range.clone());
1542 self.notify.row_removed(range.start, range.len())
1543 }
1544 }
1545
1546 origin_model.remove_range(25..110);
1547 check_all();
1548
1549 origin_model.extend(900..910);
1550 origin_model.set_row_data(45, 44444);
1551 origin_model.remove_range(10..30);
1552 origin_model.insert(45, 3000);
1553 origin_model.insert(45, 3001);
1554 origin_model.insert(45, 3002);
1555 origin_model.insert(45, 3003);
1556 origin_model.insert(45, 3004);
1557 origin_model.insert(45, 3006);
1558 origin_model.insert(45, 3007);
1559 check_all();
1560}