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