ferroui_dynamic_data/list/
change_set.rs1use super::{Change, ListChangeReason};
4use std::fmt;
5use std::ops::Deref;
6use std::rc::Rc;
7
8pub struct ChangeSet<T> {
11 changes: Rc<Vec<Change<T>>>,
12}
13
14impl<T> Clone for ChangeSet<T> {
15 fn clone(&self) -> Self {
16 Self { changes: self.changes.clone() }
17 }
18}
19
20impl<T> Default for ChangeSet<T> {
21 fn default() -> Self {
22 Self::empty()
23 }
24}
25
26impl<T> ChangeSet<T> {
27 pub fn empty() -> Self {
29 Self { changes: Rc::new(Vec::new()) }
30 }
31
32 pub fn changes(&self) -> &[Change<T>] {
34 &self.changes
35 }
36
37 pub fn count(&self) -> usize {
39 self.changes.len()
40 }
41
42 pub fn adds(&self) -> usize {
44 self.changes
45 .iter()
46 .map(|change| match change.reason() {
47 ListChangeReason::Add => 1,
48 ListChangeReason::AddRange => change.range().count(),
49 _ => 0,
50 })
51 .sum()
52 }
53
54 pub fn moves(&self) -> usize {
56 self.changes.iter().filter(|change| change.reason() == ListChangeReason::Moved).count()
57 }
58
59 pub fn refreshes(&self) -> usize {
61 self.changes.iter().filter(|change| change.reason() == ListChangeReason::Refresh).count()
62 }
63
64 pub fn removes(&self) -> usize {
66 self.changes
67 .iter()
68 .map(|change| match change.reason() {
69 ListChangeReason::Remove => 1,
70 ListChangeReason::RemoveRange | ListChangeReason::Clear => change.range().count(),
71 _ => 0,
72 })
73 .sum()
74 }
75
76 pub fn replaced(&self) -> usize {
78 self.changes.iter().filter(|change| change.reason() == ListChangeReason::Replace).count()
79 }
80
81 pub fn total_changes(&self) -> usize {
83 self.adds() + self.removes() + self.refreshes() + self.replaced() + self.moves()
84 }
85
86 pub fn ptr_eq(&self, other: &Self) -> bool {
88 Rc::ptr_eq(&self.changes, &other.changes)
89 }
90}
91
92impl<T> From<Vec<Change<T>>> for ChangeSet<T> {
93 fn from(changes: Vec<Change<T>>) -> Self {
94 Self { changes: Rc::new(changes) }
95 }
96}
97
98impl<T> FromIterator<Change<T>> for ChangeSet<T> {
99 fn from_iter<I: IntoIterator<Item = Change<T>>>(iter: I) -> Self {
100 Self::from(iter.into_iter().collect::<Vec<_>>())
101 }
102}
103
104impl<T> Deref for ChangeSet<T> {
105 type Target = [Change<T>];
106
107 fn deref(&self) -> &Self::Target {
108 &self.changes
109 }
110}
111
112impl<'a, T> IntoIterator for &'a ChangeSet<T> {
113 type Item = &'a Change<T>;
114 type IntoIter = std::slice::Iter<'a, Change<T>>;
115
116 fn into_iter(self) -> Self::IntoIter {
117 self.changes.iter()
118 }
119}
120
121impl<T: PartialEq> PartialEq for ChangeSet<T> {
122 fn eq(&self, other: &Self) -> bool {
123 self.changes == other.changes
124 }
125}
126
127impl<T: fmt::Debug> fmt::Debug for ChangeSet<T> {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 f.debug_list().entries(self.changes.iter()).finish()
130 }
131}
132
133pub trait IChangeSet<T>: Clone + 'static {
136 fn change_set(&self) -> &ChangeSet<T>;
138}
139
140impl<T: 'static> IChangeSet<T> for ChangeSet<T> {
141 fn change_set(&self) -> &ChangeSet<T> {
142 self
143 }
144}