1use crate::items::StandardListViewItem;
9use crate::{Property, SharedString, SharedVector};
10pub use adapters::{FilterModel, MapModel, ReverseModel, SortModel};
11use alloc::boxed::Box;
12use alloc::rc::Rc;
13use alloc::vec::Vec;
14use core::cell::{Cell, RefCell};
15use core::pin::Pin;
16#[allow(unused)]
17use euclid::num::{Ceil, Floor};
18pub use model_peer::*;
19use once_cell::unsync::OnceCell;
20use pin_project::pin_project;
21
22mod adapters;
23mod model_peer;
24mod repeater;
25
26pub use repeater::{Conditional, RepeatedItemTree, Repeater, RepeaterTracker};
27
28pub trait ModelTracker {
32 fn attach_peer(&self, peer: ModelPeer);
34 fn track_row_count_changes(&self);
37 fn track_row_data_changes(&self, row: usize);
40}
41
42impl ModelTracker for () {
43 fn attach_peer(&self, _peer: ModelPeer) {}
44
45 fn track_row_count_changes(&self) {}
46 fn track_row_data_changes(&self, _row: usize) {}
47}
48
49pub trait Model {
118 type Data;
120 fn row_count(&self) -> usize;
122 fn row_data(&self, row: usize) -> Option<Self::Data>;
129 fn set_row_data(&self, _row: usize, _data: Self::Data) {
139 #[cfg(feature = "std")]
140 crate::debug_log!(
141 "Model::set_row_data called on a model of type {} which does not re-implement this method. \
142 This happens when trying to modify a read-only model",
143 core::any::type_name::<Self>(),
144 );
145 }
146
147 fn model_tracker(&self) -> &dyn ModelTracker;
151
152 fn iter(&self) -> ModelIterator<'_, Self::Data>
154 where
155 Self: Sized,
156 {
157 ModelIterator::new(self)
158 }
159
160 fn as_any(&self) -> &dyn core::any::Any {
227 &()
228 }
229}
230
231pub trait ModelExt: Model {
233 fn row_data_tracked(&self, row: usize) -> Option<Self::Data> {
240 self.model_tracker().track_row_data_changes(row);
241 self.row_data(row)
242 }
243
244 fn map<F, U>(self, map_function: F) -> MapModel<Self, F>
247 where
248 Self: Sized + 'static,
249 F: Fn(Self::Data) -> U + 'static,
250 {
251 MapModel::new(self, map_function)
252 }
253
254 fn filter<F>(self, filter_function: F) -> FilterModel<Self, F>
257 where
258 Self: Sized + 'static,
259 F: Fn(&Self::Data) -> bool + 'static,
260 {
261 FilterModel::new(self, filter_function)
262 }
263
264 #[must_use]
267 fn sort(self) -> SortModel<Self, adapters::AscendingSortHelper>
268 where
269 Self: Sized + 'static,
270 Self::Data: core::cmp::Ord,
271 {
272 SortModel::new_ascending(self)
273 }
274
275 fn sort_by<F>(self, sort_function: F) -> SortModel<Self, F>
278 where
279 Self: Sized + 'static,
280 F: FnMut(&Self::Data, &Self::Data) -> core::cmp::Ordering + 'static,
281 {
282 SortModel::new(self, sort_function)
283 }
284
285 fn reverse(self) -> ReverseModel<Self>
288 where
289 Self: Sized + 'static,
290 {
291 ReverseModel::new(self)
292 }
293}
294
295impl<T: Model> ModelExt for T {}
296
297pub struct ModelIterator<'a, T> {
300 model: &'a dyn Model<Data = T>,
301 row: usize,
302}
303
304impl<'a, T> ModelIterator<'a, T> {
305 pub fn new(model: &'a dyn Model<Data = T>) -> Self {
308 Self { model, row: 0 }
309 }
310}
311
312impl<T> Iterator for ModelIterator<'_, T> {
313 type Item = T;
314
315 fn next(&mut self) -> Option<Self::Item> {
316 if self.row >= self.model.row_count() {
317 return None;
318 }
319 let row = self.row;
320 self.row += 1;
321 self.model.row_data(row)
322 }
323
324 fn size_hint(&self) -> (usize, Option<usize>) {
325 let len = self.model.row_count();
326 (len, Some(len))
327 }
328
329 fn nth(&mut self, n: usize) -> Option<Self::Item> {
330 self.row = self.row.checked_add(n)?;
331 self.next()
332 }
333}
334
335impl<T> ExactSizeIterator for ModelIterator<'_, T> {}
336
337impl<M: Model> Model for Rc<M> {
338 type Data = M::Data;
339
340 fn row_count(&self) -> usize {
341 (**self).row_count()
342 }
343
344 fn row_data(&self, row: usize) -> Option<Self::Data> {
345 (**self).row_data(row)
346 }
347
348 fn model_tracker(&self) -> &dyn ModelTracker {
349 (**self).model_tracker()
350 }
351
352 fn as_any(&self) -> &dyn core::any::Any {
353 (**self).as_any()
354 }
355 fn set_row_data(&self, row: usize, data: Self::Data) {
356 (**self).set_row_data(row, data)
357 }
358}
359
360pub struct VecModel<T> {
362 array: RefCell<Vec<T>>,
363 notify: ModelNotify,
364}
365
366impl<T> Default for VecModel<T> {
367 fn default() -> Self {
368 Self { array: Default::default(), notify: Default::default() }
369 }
370}
371
372impl<T: 'static> VecModel<T> {
373 pub fn from_slice(slice: &[T]) -> ModelRc<T>
375 where
376 T: Clone,
377 {
378 ModelRc::new(Self::from(slice.to_vec()))
379 }
380
381 pub fn push(&self, value: T) {
383 self.array.borrow_mut().push(value);
384 self.notify.row_added(self.array.borrow().len() - 1, 1)
385 }
386
387 pub fn insert(&self, index: usize, value: T) {
390 self.array.borrow_mut().insert(index, value);
391 self.notify.row_added(index, 1)
392 }
393
394 pub fn remove(&self, index: usize) -> T {
398 let r = self.array.borrow_mut().remove(index);
399 self.notify.row_removed(index, 1);
400 r
401 }
402
403 pub fn set_vec(&self, new: impl Into<Vec<T>>) {
405 *self.array.borrow_mut() = new.into();
406 self.notify.reset();
407 }
408
409 pub fn extend<I: IntoIterator<Item = T>>(&self, iter: I) {
413 let mut array = self.array.borrow_mut();
414 let old_idx = array.len();
415 array.extend(iter);
416 let count = array.len() - old_idx;
417 drop(array);
418 self.notify.row_added(old_idx, count);
419 }
420
421 pub fn clear(&self) {
425 self.array.borrow_mut().clear();
426 self.notify.reset();
427 }
428
429 pub fn swap(&self, a: usize, b: usize) {
431 if a == b {
432 return;
433 }
434
435 self.array.borrow_mut().swap(a, b);
436 self.notify.row_changed(a);
437 self.notify.row_changed(b);
438 }
439}
440
441impl<T: Clone + 'static> VecModel<T> {
442 pub fn extend_from_slice(&self, src: &[T]) {
446 let mut array = self.array.borrow_mut();
447 let old_idx = array.len();
448
449 array.extend_from_slice(src);
450 drop(array);
451 self.notify.row_added(old_idx, src.len());
452 }
453}
454
455impl<T> From<Vec<T>> for VecModel<T> {
456 fn from(array: Vec<T>) -> Self {
457 VecModel { array: RefCell::new(array), notify: Default::default() }
458 }
459}
460
461impl<T> FromIterator<T> for VecModel<T> {
462 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
463 VecModel::from(Vec::from_iter(iter))
464 }
465}
466
467impl<T: Clone + 'static> Model for VecModel<T> {
468 type Data = T;
469
470 fn row_count(&self) -> usize {
471 self.array.borrow().len()
472 }
473
474 fn row_data(&self, row: usize) -> Option<Self::Data> {
475 self.array.borrow().get(row).cloned()
476 }
477
478 fn set_row_data(&self, row: usize, data: Self::Data) {
479 if row < self.row_count() {
480 self.array.borrow_mut()[row] = data;
481 self.notify.row_changed(row);
482 }
483 }
484
485 fn model_tracker(&self) -> &dyn ModelTracker {
486 &self.notify
487 }
488
489 fn as_any(&self) -> &dyn core::any::Any {
490 self
491 }
492}
493
494#[derive(Default)]
496pub struct SharedVectorModel<T> {
497 array: RefCell<SharedVector<T>>,
498 notify: ModelNotify,
499}
500
501impl<T: Clone + 'static> SharedVectorModel<T> {
502 pub fn push(&self, value: T) {
504 self.array.borrow_mut().push(value);
505 self.notify.row_added(self.array.borrow().len() - 1, 1)
506 }
507}
508
509impl<T> SharedVectorModel<T> {
510 pub fn shared_vector(&self) -> SharedVector<T> {
512 self.array.borrow_mut().clone()
513 }
514}
515
516impl<T> From<SharedVector<T>> for SharedVectorModel<T> {
517 fn from(array: SharedVector<T>) -> Self {
518 SharedVectorModel { array: RefCell::new(array), notify: Default::default() }
519 }
520}
521
522impl<T: Clone + 'static> Model for SharedVectorModel<T> {
523 type Data = T;
524
525 fn row_count(&self) -> usize {
526 self.array.borrow().len()
527 }
528
529 fn row_data(&self, row: usize) -> Option<Self::Data> {
530 self.array.borrow().get(row).cloned()
531 }
532
533 fn set_row_data(&self, row: usize, data: Self::Data) {
534 self.array.borrow_mut().make_mut_slice()[row] = data;
535 self.notify.row_changed(row);
536 }
537
538 fn model_tracker(&self) -> &dyn ModelTracker {
539 &self.notify
540 }
541
542 fn as_any(&self) -> &dyn core::any::Any {
543 self
544 }
545}
546
547impl Model for usize {
548 type Data = i32;
549
550 fn row_count(&self) -> usize {
551 *self
552 }
553
554 fn row_data(&self, row: usize) -> Option<Self::Data> {
555 (row < self.row_count()).then_some(row as i32)
556 }
557
558 fn as_any(&self) -> &dyn core::any::Any {
559 self
560 }
561
562 fn model_tracker(&self) -> &dyn ModelTracker {
563 &()
564 }
565}
566
567impl Model for bool {
568 type Data = ();
569
570 fn row_count(&self) -> usize {
571 if *self { 1 } else { 0 }
572 }
573
574 fn row_data(&self, row: usize) -> Option<Self::Data> {
575 (row < self.row_count()).then_some(())
576 }
577
578 fn as_any(&self) -> &dyn core::any::Any {
579 self
580 }
581
582 fn model_tracker(&self) -> &dyn ModelTracker {
583 &()
584 }
585}
586
587pub struct ModelRc<T>(Option<Rc<dyn Model<Data = T>>>);
699
700impl<T> core::fmt::Debug for ModelRc<T> {
701 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
702 write!(f, "ModelRc(dyn Model)")
703 }
704}
705
706impl<T> Clone for ModelRc<T> {
707 fn clone(&self) -> Self {
708 Self(self.0.clone())
709 }
710}
711
712impl<T> Default for ModelRc<T> {
713 fn default() -> Self {
715 Self(None)
716 }
717}
718
719impl<T> core::cmp::PartialEq for ModelRc<T> {
720 fn eq(&self, other: &Self) -> bool {
721 match (&self.0, &other.0) {
722 (None, None) => true,
723 (Some(a), Some(b)) => core::ptr::eq(
724 (&**a) as *const dyn Model<Data = T> as *const u8,
725 (&**b) as *const dyn Model<Data = T> as *const u8,
726 ),
727 _ => false,
728 }
729 }
730}
731
732#[cfg(feature = "serde")]
733use serde::ser::SerializeSeq;
734#[cfg(feature = "serde")]
735impl<T> serde::Serialize for ModelRc<T>
736where
737 T: serde::Serialize,
738{
739 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
740 where
741 S: serde::Serializer,
742 {
743 let mut seq = serializer.serialize_seq(Some(self.row_count()))?;
744 for item in self.iter() {
745 seq.serialize_element(&item)?;
746 }
747 seq.end()
748 }
749}
750
751#[cfg(feature = "serde")]
752impl<'de, T> serde::Deserialize<'de> for ModelRc<T>
753where
754 T: serde::Deserialize<'de> + Clone + 'static,
755{
756 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
757 where
758 D: serde::Deserializer<'de>,
759 {
760 let vec = Vec::<T>::deserialize(deserializer)?;
761 if vec.is_empty() {
762 return Ok(ModelRc::default());
763 }
764 Ok(ModelRc::new(VecModel::from(vec)))
765 }
766}
767
768impl<T> ModelRc<T> {
769 pub fn new(model: impl Model<Data = T> + 'static) -> Self {
770 Self(Some(Rc::new(model)))
771 }
772}
773
774impl<T, M: Model<Data = T> + 'static> From<Rc<M>> for ModelRc<T> {
775 fn from(model: Rc<M>) -> Self {
776 Self(Some(model))
777 }
778}
779
780impl<T> From<Rc<dyn Model<Data = T> + 'static>> for ModelRc<T> {
781 fn from(model: Rc<dyn Model<Data = T> + 'static>) -> Self {
782 Self(Some(model))
783 }
784}
785
786impl<T: Clone + 'static> From<&[T]> for ModelRc<T> {
787 fn from(slice: &[T]) -> Self {
788 VecModel::from_slice(slice)
789 }
790}
791
792impl<T: Clone + 'static, const N: usize> From<[T; N]> for ModelRc<T> {
793 fn from(array: [T; N]) -> Self {
794 VecModel::from_slice(&array)
795 }
796}
797
798impl<T> TryInto<Rc<dyn Model<Data = T>>> for ModelRc<T> {
799 type Error = ();
800
801 fn try_into(self) -> Result<Rc<dyn Model<Data = T>>, Self::Error> {
802 self.0.ok_or(())
803 }
804}
805
806impl<T> Model for ModelRc<T> {
807 type Data = T;
808
809 fn row_count(&self) -> usize {
810 self.0.as_ref().map_or(0, |model| model.row_count())
811 }
812
813 fn row_data(&self, row: usize) -> Option<Self::Data> {
814 self.0.as_ref().and_then(|model| model.row_data(row))
815 }
816
817 fn set_row_data(&self, row: usize, data: Self::Data) {
818 if let Some(model) = self.0.as_ref() {
819 model.set_row_data(row, data);
820 }
821 }
822
823 fn model_tracker(&self) -> &dyn ModelTracker {
824 self.0.as_ref().map_or(&(), |model| model.model_tracker())
825 }
826
827 fn as_any(&self) -> &dyn core::any::Any {
828 self.0.as_ref().map_or(&(), |model| model.as_any())
829 }
830}
831
832impl From<SharedString> for StandardListViewItem {
833 fn from(value: SharedString) -> Self {
834 StandardListViewItem { text: value }
835 }
836}
837
838impl From<&str> for StandardListViewItem {
839 fn from(value: &str) -> Self {
840 StandardListViewItem { text: value.into() }
841 }
842}
843
844#[cfg(test)]
845mod tests {
846 use super::*;
847 use std::vec;
848
849 #[cfg(feature = "serde")]
850 #[test]
851 fn test_serialize_deserialize_modelrc() {
852 let model_rc = ModelRc::new(VecModel::from(vec![1, 2, 3]));
853 let serialized = serde_json::to_string(&model_rc).unwrap();
854 let deserialized: ModelRc<i32> = serde_json::from_str(&serialized).unwrap();
855 assert_eq!(deserialized.row_count(), 3);
856 assert_eq!(deserialized.row_data(0), Some(1));
857 assert_eq!(deserialized.row_data(1), Some(2));
858 assert_eq!(deserialized.row_data(2), Some(3));
859 }
860
861 #[test]
862 fn test_tracking_model_handle() {
863 let model: Rc<VecModel<u8>> = Rc::new(Default::default());
864 let handle = ModelRc::from(model.clone() as Rc<dyn Model<Data = u8>>);
865 let tracker = Box::pin(<crate::properties::PropertyTracker>::default());
866 assert_eq!(
867 tracker.as_ref().evaluate(|| {
868 handle.model_tracker().track_row_count_changes();
869 handle.row_count()
870 }),
871 0
872 );
873 assert!(!tracker.is_dirty());
874 model.push(42);
875 model.push(100);
876 assert!(tracker.is_dirty());
877 assert_eq!(
878 tracker.as_ref().evaluate(|| {
879 handle.model_tracker().track_row_count_changes();
880 handle.row_count()
881 }),
882 2
883 );
884 assert!(!tracker.is_dirty());
885 model.set_row_data(0, 41);
886 assert!(!tracker.is_dirty());
887 model.remove(0);
888 assert!(tracker.is_dirty());
889 assert_eq!(
890 tracker.as_ref().evaluate(|| {
891 handle.model_tracker().track_row_count_changes();
892 handle.row_count()
893 }),
894 1
895 );
896 assert!(!tracker.is_dirty());
897 model.set_vec(vec![1, 2, 3]);
898 assert!(tracker.is_dirty());
899 }
900
901 #[test]
902 fn test_data_tracking() {
903 let model: Rc<VecModel<u8>> = Rc::new(VecModel::from(vec![0, 1, 2, 3, 4]));
904 let handle = ModelRc::from(model.clone());
905 let tracker = Box::pin(<crate::properties::PropertyTracker>::default());
906 assert_eq!(
907 tracker.as_ref().evaluate(|| {
908 handle.model_tracker().track_row_data_changes(1);
909 handle.row_data(1).unwrap()
910 }),
911 1
912 );
913 assert!(!tracker.is_dirty());
914
915 model.set_row_data(2, 42);
916 assert!(!tracker.is_dirty());
917 model.set_row_data(1, 100);
918 assert!(tracker.is_dirty());
919
920 assert_eq!(
921 tracker.as_ref().evaluate(|| {
922 handle.model_tracker().track_row_data_changes(1);
923 handle.row_data(1).unwrap()
924 }),
925 100
926 );
927 assert!(!tracker.is_dirty());
928
929 model.push(200);
932 assert!(tracker.is_dirty());
933
934 assert_eq!(tracker.as_ref().evaluate(|| { handle.row_data_tracked(1).unwrap() }), 100);
935 assert!(!tracker.is_dirty());
936
937 model.insert(0, 255);
938 assert!(tracker.is_dirty());
939
940 model.set_vec(Vec::new());
941 assert!(tracker.is_dirty());
942 }
943
944 #[derive(Default)]
945 struct TestView {
946 changed_rows: RefCell<Vec<(usize, usize)>>,
950 added_rows: RefCell<Vec<(usize, usize, usize)>>,
951 removed_rows: RefCell<Vec<(usize, usize, usize)>>,
952 reset: RefCell<usize>,
953 model: RefCell<Option<std::rc::Weak<dyn Model<Data = i32>>>>,
954 }
955 impl TestView {
956 fn clear(&self) {
957 self.changed_rows.borrow_mut().clear();
958 self.added_rows.borrow_mut().clear();
959 self.removed_rows.borrow_mut().clear();
960 *self.reset.borrow_mut() = 0;
961 }
962 fn row_count(&self) -> usize {
963 self.model
964 .borrow()
965 .as_ref()
966 .and_then(|model| model.upgrade())
967 .map_or(0, |model| model.row_count())
968 }
969 }
970 impl ModelChangeListener for TestView {
971 fn row_changed(self: Pin<&Self>, row: usize) {
972 self.changed_rows.borrow_mut().push((row, self.row_count()));
973 }
974
975 fn row_added(self: Pin<&Self>, index: usize, count: usize) {
976 self.added_rows.borrow_mut().push((index, count, self.row_count()));
977 }
978
979 fn row_removed(self: Pin<&Self>, index: usize, count: usize) {
980 self.removed_rows.borrow_mut().push((index, count, self.row_count()));
981 }
982 fn reset(self: Pin<&Self>) {
983 *self.reset.borrow_mut() += 1;
984 }
985 }
986
987 #[test]
988 fn test_vecmodel_set_vec() {
989 let view = Box::pin(ModelChangeListenerContainer::<TestView>::default());
990
991 let model = Rc::new(VecModel::from(vec![1i32, 2, 3, 4]));
992 model.model_tracker().attach_peer(Pin::as_ref(&view).model_peer());
993 *view.model.borrow_mut() =
994 Some(std::rc::Rc::downgrade(&(model.clone() as Rc<dyn Model<Data = i32>>)));
995
996 model.push(5);
997 assert!(view.changed_rows.borrow().is_empty());
998 assert_eq!(&*view.added_rows.borrow(), &[(4, 1, 5)]);
999 assert!(view.removed_rows.borrow().is_empty());
1000 assert_eq!(*view.reset.borrow(), 0);
1001 view.clear();
1002
1003 model.set_vec(vec![6, 7, 8]);
1004 assert!(view.changed_rows.borrow().is_empty());
1005 assert!(view.added_rows.borrow().is_empty());
1006 assert!(view.removed_rows.borrow().is_empty());
1007 assert_eq!(*view.reset.borrow(), 1);
1008 view.clear();
1009
1010 model.extend_from_slice(&[9, 10, 11]);
1011 assert!(view.changed_rows.borrow().is_empty());
1012 assert_eq!(&*view.added_rows.borrow(), &[(3, 3, 6)]);
1013 assert!(view.removed_rows.borrow().is_empty());
1014 assert_eq!(*view.reset.borrow(), 0);
1015 view.clear();
1016
1017 model.extend([12, 13]);
1018 assert!(view.changed_rows.borrow().is_empty());
1019 assert_eq!(&*view.added_rows.borrow(), &[(6, 2, 8)]);
1020 assert!(view.removed_rows.borrow().is_empty());
1021 assert_eq!(*view.reset.borrow(), 0);
1022 view.clear();
1023
1024 assert_eq!(model.iter().collect::<Vec<_>>(), vec![6, 7, 8, 9, 10, 11, 12, 13]);
1025
1026 model.swap(1, 1);
1027 assert!(view.changed_rows.borrow().is_empty());
1028 assert!(view.added_rows.borrow().is_empty());
1029 assert!(view.removed_rows.borrow().is_empty());
1030 assert_eq!(*view.reset.borrow(), 0);
1031 view.clear();
1032
1033 model.swap(1, 2);
1034 assert_eq!(&*view.changed_rows.borrow(), &[(1, 8), (2, 8)]);
1035 assert!(view.added_rows.borrow().is_empty());
1036 assert!(view.removed_rows.borrow().is_empty());
1037 assert_eq!(*view.reset.borrow(), 0);
1038 view.clear();
1039
1040 assert_eq!(model.iter().collect::<Vec<_>>(), vec![6, 8, 7, 9, 10, 11, 12, 13]);
1041 }
1042
1043 #[test]
1044 fn test_vecmodel_clear() {
1045 let view = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1046
1047 let model = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1048 model.model_tracker().attach_peer(Pin::as_ref(&view).model_peer());
1049 *view.model.borrow_mut() =
1050 Some(std::rc::Rc::downgrade(&(model.clone() as Rc<dyn Model<Data = i32>>)));
1051
1052 model.clear();
1053 assert_eq!(*view.reset.borrow(), 1);
1054 assert_eq!(model.row_count(), 0);
1055 }
1056
1057 #[test]
1058 fn test_vecmodel_swap() {
1059 let view = Box::pin(ModelChangeListenerContainer::<TestView>::default());
1060
1061 let model = Rc::new(VecModel::from(vec![1, 2, 3, 4]));
1062 model.model_tracker().attach_peer(Pin::as_ref(&view).model_peer());
1063 *view.model.borrow_mut() =
1064 Some(std::rc::Rc::downgrade(&(model.clone() as Rc<dyn Model<Data = i32>>)));
1065
1066 model.swap(1, 1);
1067 assert!(view.changed_rows.borrow().is_empty());
1068 assert!(view.added_rows.borrow().is_empty());
1069 assert!(view.removed_rows.borrow().is_empty());
1070 assert_eq!(*view.reset.borrow(), 0);
1071 view.clear();
1072
1073 model.swap(1, 2);
1074 assert_eq!(&*view.changed_rows.borrow(), &[(1, 4), (2, 4)]);
1075 assert!(view.added_rows.borrow().is_empty());
1076 assert!(view.removed_rows.borrow().is_empty());
1077 assert_eq!(*view.reset.borrow(), 0);
1078 view.clear();
1079 }
1080
1081 #[test]
1082 fn modeliter_in_bounds() {
1083 struct TestModel {
1084 length: usize,
1085 max_requested_row: Cell<usize>,
1086 notify: ModelNotify,
1087 }
1088
1089 impl Model for TestModel {
1090 type Data = usize;
1091
1092 fn row_count(&self) -> usize {
1093 self.length
1094 }
1095
1096 fn row_data(&self, row: usize) -> Option<usize> {
1097 self.max_requested_row.set(self.max_requested_row.get().max(row));
1098 (row < self.length).then_some(row)
1099 }
1100
1101 fn model_tracker(&self) -> &dyn ModelTracker {
1102 &self.notify
1103 }
1104 }
1105
1106 let model = Rc::new(TestModel {
1107 length: 10,
1108 max_requested_row: Cell::new(0),
1109 notify: Default::default(),
1110 });
1111
1112 assert_eq!(model.iter().max().unwrap(), 9);
1113 assert_eq!(model.max_requested_row.get(), 9);
1114 }
1115
1116 #[test]
1117 fn vecmodel_doesnt_require_default() {
1118 #[derive(Clone)]
1119 struct MyNoDefaultType {
1120 _foo: bool,
1121 }
1122 let model = VecModel::<MyNoDefaultType>::default();
1123 assert_eq!(model.row_count(), 0);
1124 model.push(MyNoDefaultType { _foo: true });
1125 }
1126}