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 if index + count < self.wrapped_model.row_count() {
726 for row in self.mapping.borrow_mut().iter_mut() {
727 if *row >= index {
728 *row += count;
729 }
730 }
731 }
732
733 for row in index..(index + count) {
734 let insertion_index = if let Some(added_data) = self.wrapped_model.row_data(row) {
735 self.mapping.borrow().partition_point(|existing_row| {
736 self.wrapped_model.row_data(*existing_row).is_some_and(|existing| {
737 self.sort_helper.borrow_mut().cmp(&existing, &added_data)
738 == core::cmp::Ordering::Less
739 })
740 })
741 } else {
742 self.mapping.borrow().len()
743 };
744 self.mapping.borrow_mut().insert(insertion_index, row);
745 self.notify.row_added(insertion_index, 1)
746 }
747 }
748
749 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
750 if count == 0 {
751 return;
752 }
753
754 if self.sorted_rows_dirty.get() {
755 self.reset();
756 return;
757 }
758
759 let mut removed_rows = Vec::new();
760 let mut mapping = self.mapping.borrow_mut();
761
762 let mut write = 0;
765 for read in 0..mapping.len() {
766 let sort_index = mapping[read];
767 if (index..index + count).contains(&sort_index) {
768 removed_rows.push(write);
769 continue;
770 }
771 mapping[write] = if sort_index >= index { sort_index - count } else { sort_index };
772 write += 1;
773 }
774 mapping.truncate(write);
775 drop(mapping);
776
777 for removed_row in removed_rows {
778 self.notify.row_removed(removed_row, 1);
779 }
780 }
781
782 fn reset(self: Pin<&Self>) {
783 self.sorted_rows_dirty.set(true);
784 self.notify.reset();
785 }
786}
787
788pub struct SortModel<M, F>(ModelChangeListenerBox<SortModelInner<M, F>>)
882where
883 M: Model + 'static,
884 F: SortHelper<M::Data> + 'static;
885
886impl<M, F> SortModel<M, F>
887where
888 M: Model + 'static,
889 F: FnMut(&M::Data, &M::Data) -> core::cmp::Ordering + 'static,
890{
891 pub fn new(wrapped_model: M, sort_function: F) -> Self
894 where
895 F: FnMut(&M::Data, &M::Data) -> core::cmp::Ordering + 'static,
896 {
897 let sorted_model_inner = SortModelInner {
898 wrapped_model,
899 sort_helper: RefCell::new(sort_function),
900 mapping: RefCell::new(Vec::new()),
901 notify: Default::default(),
902 sorted_rows_dirty: Cell::new(true),
903 };
904
905 let container = ModelChangeListenerBox::new(sorted_model_inner);
906
907 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
908
909 Self(container)
910 }
911}
912
913impl<M> SortModel<M, AscendingSortHelper>
914where
915 M: Model + 'static,
916 M::Data: core::cmp::Ord,
917{
918 pub fn new_ascending(wrapped_model: M) -> Self
921 where
922 M::Data: core::cmp::Ord,
923 {
924 let sorted_model_inner = SortModelInner {
925 wrapped_model,
926 sort_helper: RefCell::new(AscendingSortHelper),
927 mapping: RefCell::new(Vec::new()),
928 notify: Default::default(),
929 sorted_rows_dirty: Cell::new(true),
930 };
931
932 let container = ModelChangeListenerBox::new(sorted_model_inner);
933
934 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
935
936 Self(container)
937 }
938}
939
940impl<M, S> SortModel<M, S>
941where
942 M: Model + 'static,
943 S: SortHelper<M::Data>,
944{
945 pub fn source_model(&self) -> &M {
947 &self.0.as_ref().get().get_ref().wrapped_model
948 }
949
950 pub fn reset(&self) {
953 self.0.as_ref().get().reset();
954 }
955
956 pub fn unsorted_row(&self, sorted_row: usize) -> usize {
958 self.0.build_mapping_vec();
959 self.0.mapping.borrow()[sorted_row]
960 }
961}
962
963impl<M, S> Model for SortModel<M, S>
964where
965 M: Model + 'static,
966 S: SortHelper<M::Data>,
967{
968 type Data = M::Data;
969
970 fn row_count(&self) -> usize {
971 self.0.wrapped_model.row_count()
972 }
973
974 fn row_data(&self, row: usize) -> Option<Self::Data> {
975 self.0.build_mapping_vec();
976
977 self.0
978 .mapping
979 .borrow()
980 .get(row)
981 .and_then(|&wrapped_row| self.0.wrapped_model.row_data(wrapped_row))
982 }
983
984 fn set_row_data(&self, row: usize, data: Self::Data) {
985 let wrapped_row = self.0.mapping.borrow()[row];
986 self.0.wrapped_model.set_row_data(wrapped_row, data);
987 }
988
989 fn model_tracker(&self) -> &dyn ModelTracker {
990 &self.0.notify
991 }
992
993 fn as_any(&self) -> &dyn core::any::Any {
994 self
995 }
996}
997
998#[cfg(test)]
999mod sort_tests {
1000 use super::*;
1001 use std::vec;
1002 use tests_helper::*;
1003
1004 #[test]
1005 fn test_sorted_model_insert() {
1006 let wrapped_rc = Rc::new(VecModel::from(std::vec![3, 4, 1, 2]));
1007 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1008
1009 let _checker = ModelChecker::new(sorted_model.clone());
1010
1011 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1012 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1013
1014 assert_eq!(sorted_model.row_count(), 4);
1015 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1016 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1017 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1018 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1019
1020 wrapped_rc.insert(0, 10);
1021
1022 assert_eq!(observer.added_rows.borrow().len(), 1);
1023 assert!(observer.added_rows.borrow().eq(&[(4, 1)]));
1024 assert!(observer.changed_rows.borrow().is_empty());
1025 assert!(observer.removed_rows.borrow().is_empty());
1026 assert_eq!(*observer.reset.borrow(), 0);
1027 observer.clear();
1028
1029 assert_eq!(sorted_model.row_count(), 5);
1030 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1031 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1032 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1033 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1034 assert_eq!(sorted_model.row_data(4).unwrap(), 10);
1035 }
1036
1037 #[test]
1038 fn test_sorted_model_remove() {
1039 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1040 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1041
1042 let _checker = ModelChecker::new(sorted_model.clone());
1043
1044 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1045 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1046
1047 assert_eq!(sorted_model.row_count(), 4);
1048 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1049 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1050 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1051 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1052
1053 wrapped_rc.remove(1);
1055
1056 assert!(observer.added_rows.borrow().is_empty());
1057 assert!(observer.changed_rows.borrow().is_empty());
1058 assert_eq!(observer.removed_rows.borrow().len(), 1);
1059 assert!(observer.removed_rows.borrow().eq(&[(3, 1)]));
1060 assert_eq!(*observer.reset.borrow(), 0);
1061 observer.clear();
1062
1063 assert_eq!(sorted_model.row_count(), 3);
1064 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1065 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1066 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1067 }
1068
1069 #[test]
1070 fn test_sorted_model_changed() {
1071 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1072 let sorted_model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1073
1074 let _checker = ModelChecker::new(sorted_model.clone());
1075
1076 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1077 sorted_model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1078
1079 assert_eq!(sorted_model.row_count(), 4);
1080 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1081 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1082 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1083 assert_eq!(sorted_model.row_data(3).unwrap(), 4);
1084
1085 wrapped_rc.set_row_data(1, 10);
1087
1088 assert!(observer.added_rows.borrow().is_empty());
1089 assert_eq!(observer.changed_rows.borrow().len(), 1);
1090 assert_eq!(*observer.changed_rows.borrow().first().unwrap(), 3);
1091 assert!(observer.removed_rows.borrow().is_empty());
1092 assert_eq!(*observer.reset.borrow(), 0);
1093 observer.clear();
1094
1095 assert_eq!(sorted_model.row_count(), 4);
1096 assert_eq!(sorted_model.row_data(0).unwrap(), 1);
1097 assert_eq!(sorted_model.row_data(1).unwrap(), 2);
1098 assert_eq!(sorted_model.row_data(2).unwrap(), 3);
1099 assert_eq!(sorted_model.row_data(3).unwrap(), 10);
1100
1101 wrapped_rc.set_row_data(1, 0);
1103
1104 assert_eq!(observer.added_rows.borrow().len(), 1);
1105 assert!(observer.added_rows.borrow().first().unwrap().eq(&(0, 1)));
1106 assert!(observer.changed_rows.borrow().is_empty());
1107 assert_eq!(observer.removed_rows.borrow().len(), 1);
1108 assert!(observer.removed_rows.borrow().first().unwrap().eq(&(3, 1)));
1109 assert_eq!(*observer.reset.borrow(), 0);
1110 observer.clear();
1111
1112 assert_eq!(sorted_model.row_count(), 4);
1113 assert_eq!(sorted_model.row_data(0).unwrap(), 0);
1114 assert_eq!(sorted_model.row_data(1).unwrap(), 1);
1115 assert_eq!(sorted_model.row_data(2).unwrap(), 2);
1116 assert_eq!(sorted_model.row_data(3).unwrap(), 3);
1117 }
1118
1119 #[test]
1120 fn test_sorted_model_source_model() {
1121 let wrapped_rc = Rc::new(VecModel::from(vec![3, 4, 1, 2]));
1122 let model = Rc::new(SortModel::new(wrapped_rc.clone(), |lhs, rhs| lhs.cmp(rhs)));
1123 let _checker = ModelChecker::new(model.clone());
1124
1125 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1126 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1127
1128 model.source_model().push(6);
1129 model.source_model().push(5);
1130
1131 let expected = &[1, 2, 3, 4, 5, 6];
1132 assert_eq!(model.row_count(), expected.len());
1133 for (i, v) in expected.iter().enumerate() {
1134 assert_eq!(model.row_data(i), Some(*v), "Expected {v} at index {i}");
1135 }
1136
1137 assert!(Rc::ptr_eq(model.source_model(), &wrapped_rc));
1138 model.reset();
1139 assert_eq!(*observer.reset.borrow(), 1);
1140 }
1141
1142 #[test]
1143 fn test_sorted_broken_model() {
1144 let wrapped_rc = BrokenModel::new(std::vec![
1145 Some("1"),
1146 Some("2"),
1147 None,
1148 Some("4"),
1149 None,
1150 Some("3"),
1151 Some("0"),
1152 Some("5")
1153 ]);
1154 let model = Rc::new(SortModel::new_ascending(wrapped_rc.clone()));
1155
1156 assert_eq!(model.row_count(), 8);
1157 assert_eq!(model.row_data(0), Some("0"));
1158 assert_eq!(model.row_data(1), Some("1"));
1159 assert_eq!(model.row_data(2), Some("2"));
1160 assert_eq!(model.row_data(3), Some("3"));
1161 assert_eq!(model.row_data(4), Some("4"));
1162 assert_eq!(model.row_data(5), Some("5"));
1163 assert_eq!(model.row_data(6), None);
1164 assert_eq!(model.row_data(7), None);
1165
1166 wrapped_rc.notify.row_removed(2, 2);
1167 wrapped_rc.notify.row_added(2, 2);
1168 wrapped_rc.data.borrow_mut()[1] = None;
1169 wrapped_rc.notify.row_changed(1);
1170 wrapped_rc.data.borrow_mut()[2] = Some("a");
1171 wrapped_rc.notify.row_changed(2);
1172
1173 assert_eq!(model.row_count(), 8);
1174 assert_eq!(model.row_data(0), Some("0"));
1175 assert_eq!(model.row_data(1), Some("1"));
1176 assert_eq!(model.row_data(2), Some("3"));
1177 assert_eq!(model.row_data(3), Some("4"));
1178 assert_eq!(model.row_data(4), Some("5"));
1179 assert_eq!(model.row_data(5), Some("a"));
1180 assert_eq!(model.row_data(6), None);
1181 assert_eq!(model.row_data(7), None);
1182
1183 assert!(Rc::ptr_eq(model.source_model(), &wrapped_rc));
1184 }
1185}
1186
1187pub struct ReverseModel<M>(ModelChangeListenerBox<ReverseModelInner<M>>)
1251where
1252 M: Model + 'static;
1253
1254struct ReverseModelInner<M>
1255where
1256 M: Model + 'static,
1257{
1258 wrapped_model: M,
1259 notify: ModelNotify,
1260}
1261
1262impl<M> ModelChangeListener for ReverseModelInner<M>
1263where
1264 M: Model + 'static,
1265{
1266 fn row_changed(self: Pin<&Self>, row: usize) {
1267 self.notify.row_changed(self.wrapped_model.row_count() - 1 - row);
1268 }
1269
1270 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
1271 let row_count = self.wrapped_model.row_count();
1272 let old_row_count = row_count - count;
1273 let index = old_row_count - index;
1274 self.notify.row_added(index, count);
1275 }
1276
1277 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
1278 let row_count = self.wrapped_model.row_count();
1279 self.notify.row_removed(row_count - index, count);
1280 }
1281
1282 fn reset(self: Pin<&Self>) {
1283 self.notify.reset()
1284 }
1285}
1286
1287impl<M> ReverseModel<M>
1288where
1289 M: Model + 'static,
1290{
1291 pub fn new(wrapped_model: M) -> Self {
1294 let inner = ReverseModelInner { wrapped_model, notify: Default::default() };
1295 let container = ModelChangeListenerBox::new(inner);
1296 container.wrapped_model.model_tracker().attach_peer(container.as_ref().model_peer());
1297 Self(container)
1298 }
1299
1300 pub fn source_model(&self) -> &M {
1302 &self.0.as_ref().get().get_ref().wrapped_model
1303 }
1304}
1305
1306impl<M> Model for ReverseModel<M>
1307where
1308 M: Model + 'static,
1309{
1310 type Data = M::Data;
1311
1312 fn row_count(&self) -> usize {
1313 self.0.wrapped_model.row_count()
1314 }
1315
1316 fn row_data(&self, row: usize) -> Option<Self::Data> {
1317 let count = self.0.wrapped_model.row_count();
1318 self.0.wrapped_model.row_data(count.checked_sub(row + 1)?)
1319 }
1320 fn set_row_data(&self, row: usize, data: Self::Data) {
1321 let count = self.0.as_ref().wrapped_model.row_count();
1322 self.0.wrapped_model.set_row_data(count - row - 1, data);
1323 }
1324
1325 fn model_tracker(&self) -> &dyn ModelTracker {
1326 &self.0.notify
1327 }
1328
1329 fn as_any(&self) -> &dyn core::any::Any {
1330 self
1331 }
1332}
1333
1334#[cfg(test)]
1335mod reversed_tests {
1336 use super::*;
1337 use std::vec;
1338 use tests_helper::*;
1339
1340 #[track_caller]
1341 fn check_content(model: &ReverseModel<Rc<VecModel<i32>>>, expected: &[i32]) {
1342 assert_eq!(model.row_count(), expected.len());
1343 for (i, v) in expected.iter().enumerate() {
1344 assert_eq!(model.row_data(i), Some(*v), "Expected {v} at index {i}");
1345 }
1346 }
1347
1348 #[test]
1349 fn test_reversed_model() {
1350 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1351 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1352 let _checker = ModelChecker::new(model.clone());
1353
1354 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1355 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1356
1357 check_content(&model, &[4, 3, 2, 1]);
1358 }
1359
1360 #[test]
1361 fn test_reversed_model_insert() {
1362 for (idx, mapped_idx) in [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)] {
1363 std::println!("Inserting at {idx} expecting mapped to {mapped_idx}");
1364 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1365 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1366 let _checker = ModelChecker::new(model.clone());
1367
1368 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1369 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1370
1371 wrapped_rc.insert(idx, 10);
1372
1373 assert_eq!(observer.added_rows.borrow().len(), 1);
1374 assert!(
1375 observer.added_rows.borrow().eq(&[(mapped_idx, 1)]),
1376 "Added rows: {:?}",
1377 observer.added_rows.borrow()
1378 );
1379 assert!(observer.changed_rows.borrow().is_empty());
1380 assert!(observer.removed_rows.borrow().is_empty());
1381 assert_eq!(*observer.reset.borrow(), 0);
1382 assert_eq!(model.row_data(mapped_idx), Some(10));
1383 }
1384 }
1385
1386 #[test]
1387 fn test_reversed_model_remove() {
1388 for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
1389 std::println!("Removing at {idx} expecting mapped to {mapped_idx}");
1390 let wrapped_rc = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1391 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1392 let _checker = ModelChecker::new(model.clone());
1393
1394 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1395 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1396
1397 wrapped_rc.remove(idx);
1398
1399 assert_eq!(observer.removed_rows.borrow().len(), 1);
1400 assert!(
1401 observer.removed_rows.borrow().eq(&[(mapped_idx, 1)]),
1402 "Remove rows: {:?}",
1403 observer.removed_rows.borrow()
1404 );
1405 assert!(observer.added_rows.borrow().is_empty());
1406 assert!(observer.changed_rows.borrow().is_empty());
1407 assert_eq!(*observer.reset.borrow(), 0);
1408 }
1409 }
1410
1411 #[test]
1412 fn test_reversed_model_changed() {
1413 for (idx, mapped_idx) in [(0, 3), (1, 2), (2, 1), (3, 0)] {
1414 std::println!("Changing at {idx} expecting mapped to {mapped_idx}");
1415 let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
1416 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1417 let _checker = ModelChecker::new(model.clone());
1418
1419 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1420 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1421
1422 wrapped_rc.set_row_data(idx, 10);
1423
1424 assert_eq!(observer.changed_rows.borrow().len(), 1);
1425 assert!(
1426 observer.changed_rows.borrow().eq(&[mapped_idx]),
1427 "Changed rows: {:?}",
1428 observer.changed_rows.borrow()
1429 );
1430 assert!(observer.added_rows.borrow().is_empty());
1431 assert!(observer.removed_rows.borrow().is_empty());
1432 assert_eq!(*observer.reset.borrow(), 0);
1433 assert_eq!(model.row_data(mapped_idx), Some(10));
1434 }
1435 }
1436
1437 #[test]
1438 fn test_reversed_model_source_model() {
1439 let wrapped_rc = Rc::new(VecModel::from(std::vec![1, 2, 3, 4]));
1440 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1441 let _checker = ModelChecker::new(model.clone());
1442
1443 let observer = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1444 model.model_tracker().attach_peer(Pin::as_ref(&observer).model_peer());
1445
1446 model.source_model().push(5);
1447
1448 check_content(&model, &[5, 4, 3, 2, 1]);
1449 }
1450
1451 #[test]
1452 fn test_reversed_broken_model() {
1453 let wrapped_rc = BrokenModel::new(std::vec![Some("1"), Some("2"), None, Some("4")]);
1454 let model = Rc::new(ReverseModel::new(wrapped_rc.clone()));
1455
1456 wrapped_rc.notify.row_added(1, 3);
1457
1458 assert_eq!(model.row_count(), 4);
1459 assert_eq!(model.row_data(0), Some("4"));
1460 assert_eq!(model.row_data(1), None);
1461 assert_eq!(model.row_data(2), Some("2"));
1462 assert_eq!(model.row_data(3), Some("1"));
1463 }
1464}
1465
1466#[test]
1467fn test_long_chain_integrity() {
1468 use alloc::string::ToString;
1469 use tests_helper::*;
1470 let origin_model = Rc::new(VecModel::from((0..100).collect::<Vec<_>>()));
1471 let checker1 = ModelChecker::new(origin_model.clone());
1472 let fizzbuzz = Rc::new(MapModel::new(origin_model.clone(), |number| {
1473 if (number % 3) == 0 && (number % 5) == 0 {
1474 "FizzBuzz".to_string()
1475 } else if (number % 3) == 0 {
1476 "Fizz".to_string()
1477 } else if (number % 5) == 0 {
1478 "Buzz".to_string()
1479 } else {
1480 number.to_string()
1481 }
1482 }));
1483 let checker2 = ModelChecker::new(fizzbuzz.clone());
1484 let filter = Rc::new(FilterModel::new(fizzbuzz, |s| s != "FizzBuzz"));
1485 let checker3 = ModelChecker::new(filter.clone());
1486 let reverse = Rc::new(ReverseModel::new(filter));
1487 let checker4 = ModelChecker::new(reverse.clone());
1488 let sorted = Rc::new(SortModel::new_ascending(reverse));
1489 let checker5 = ModelChecker::new(sorted.clone());
1490 let filter2 = Rc::new(FilterModel::new(sorted, |s| s != "Fizz"));
1491 let checker6 = ModelChecker::new(filter2.clone());
1492
1493 let check_all = || {
1494 checker1.check();
1495 checker2.check();
1496 checker3.check();
1497 checker4.check();
1498 checker5.check();
1499 checker6.check();
1500 };
1501
1502 origin_model.extend(50..150);
1503 check_all();
1504 origin_model.insert(8, 1000);
1505 check_all();
1506 origin_model.remove(9);
1507 check_all();
1508 origin_model.remove(10);
1509 origin_model.remove(11);
1510 origin_model.set_row_data(55, 10001);
1511 check_all();
1512 origin_model.set_row_data(58, 10002);
1513 origin_model.set_row_data(59, 10003);
1514 origin_model.remove(28);
1515 origin_model.remove(29);
1516 origin_model.insert(100, 8888);
1517 origin_model.remove(30);
1518 origin_model.set_row_data(60, 10004);
1519 origin_model.remove(130);
1520 origin_model.set_row_data(61, 10005);
1521 origin_model.remove(131);
1522 check_all();
1523 origin_model.remove(12);
1524 origin_model.remove(13);
1525 origin_model.remove(14);
1526 origin_model.set_row_data(62, 10006);
1527 origin_model.set_row_data(63, 10007);
1528 origin_model.set_row_data(64, 10008);
1529 origin_model.set_row_data(65, 10009);
1530 check_all();
1531
1532 trait RemoveRange {
1534 fn remove_range(&self, range: core::ops::Range<usize>);
1535 }
1536 impl<T> RemoveRange for VecModel<T> {
1537 fn remove_range(&self, range: core::ops::Range<usize>) {
1538 self.array.borrow_mut().drain(range.clone());
1539 self.notify.row_removed(range.start, range.len())
1540 }
1541 }
1542
1543 origin_model.remove_range(25..110);
1544 check_all();
1545
1546 origin_model.extend(900..910);
1547 origin_model.set_row_data(45, 44444);
1548 origin_model.remove_range(10..30);
1549 origin_model.insert(45, 3000);
1550 origin_model.insert(45, 3001);
1551 origin_model.insert(45, 3002);
1552 origin_model.insert(45, 3003);
1553 origin_model.insert(45, 3004);
1554 origin_model.insert(45, 3006);
1555 origin_model.insert(45, 3007);
1556 check_all();
1557}
1558
1559#[test]
1560fn test_sorted_model_row_added_adjustment() {
1561 use tests_helper::*;
1562
1563 for insert_at in [0usize, 3, 7, 10] {
1565 let origin = Rc::new(VecModel::from(alloc::vec![50, 10, 40, 20, 30, 90, 60, 80, 70, 0]));
1566 let sorted = Rc::new(SortModel::new(origin.clone(), |lhs, rhs| lhs.cmp(rhs)));
1567 let checker = ModelChecker::new(sorted.clone());
1568 origin.insert(insert_at, 35);
1569 origin.insert(insert_at, 45);
1570 checker.check();
1571 assert_eq!(
1572 (0..sorted.row_count()).filter_map(|row| sorted.row_data(row)).collect::<Vec<_>>(),
1573 alloc::vec![0, 10, 20, 30, 35, 40, 45, 50, 60, 70, 80, 90],
1574 "inserting at {insert_at}"
1575 );
1576 }
1577
1578 let origin = Rc::new(VecModel::from(alloc::vec![50, 10, 40, 20, 30]));
1580 let sorted = Rc::new(SortModel::new(origin.clone(), |lhs, rhs| lhs.cmp(rhs)));
1581 let checker = ModelChecker::new(sorted.clone());
1582 origin.push(35);
1583 origin.push(5);
1584 origin.push(100);
1585 checker.check();
1586 assert_eq!(
1587 (0..sorted.row_count()).filter_map(|row| sorted.row_data(row)).collect::<Vec<_>>(),
1588 alloc::vec![5, 10, 20, 30, 35, 40, 50, 100]
1589 );
1590}