ferroui_dynamic_data/list/
change.rs1use super::{ChangeType, ItemChange, ListChangeReason, RangeChange};
4use std::fmt;
5
6#[derive(Clone, PartialEq, Eq, Hash)]
13pub struct Change<T> {
14 reason: ListChangeReason,
15 item: Option<ItemChange<T>>,
16 range: RangeChange<T>,
17}
18
19impl<T> Change<T> {
20 pub fn new(reason: ListChangeReason, current: T, index: Option<usize>) -> Self {
22 Self::with_previous(reason, current, None, index, None)
23 }
24
25 pub fn range_change(reason: ListChangeReason, items: Vec<T>, index: Option<usize>) -> Self {
30 assert!(reason.change_type() == ChangeType::Range, "ListChangeReason must be a range type for a range change");
31 Self { reason, item: None, range: RangeChange::new(items, index) }
32 }
33
34 pub fn moved(current: T, current_index: usize, previous_index: usize) -> Self {
36 Self {
37 reason: ListChangeReason::Moved,
38 item: Some(ItemChange::new(ListChangeReason::Moved, current, None, Some(current_index), Some(previous_index))),
39 range: RangeChange::default(),
40 }
41 }
42
43 pub fn with_previous(reason: ListChangeReason, current: T, previous: Option<T>, current_index: Option<usize>, previous_index: Option<usize>) -> Self {
50 assert!(!(reason == ListChangeReason::Add && previous.is_some()), "For ListChangeReason.Add, a previous value cannot be specified");
51 assert!(!(reason == ListChangeReason::Replace && previous.is_none()), "For ListChangeReason.Replace, must supply previous value");
52 assert!(!(reason == ListChangeReason::Refresh && current_index.is_none()), "For ListChangeReason.Refresh, must supply an index");
53 Self { reason, item: Some(ItemChange::new(reason, current, previous, current_index, previous_index)), range: RangeChange::default() }
54 }
55
56 pub fn reason(&self) -> ListChangeReason {
58 self.reason
59 }
60
61 pub fn change_type(&self) -> ChangeType {
63 self.reason.change_type()
64 }
65
66 pub fn item(&self) -> &ItemChange<T> {
71 self.item.as_ref().expect("the change of a range has no item change")
72 }
73
74 pub fn try_item(&self) -> Option<&ItemChange<T>> {
76 self.item.as_ref()
77 }
78
79 pub fn range(&self) -> &RangeChange<T> {
81 &self.range
82 }
83
84 pub(crate) fn range_mut(&mut self) -> &mut RangeChange<T> {
85 &mut self.range
86 }
87}
88
89impl<T> fmt::Debug for Change<T>
90where
91 T: fmt::Debug,
92{
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 match &self.item {
96 Some(item) => write!(f, "{:?}. {:?}", self.reason, item),
97 None => write!(f, "{:?}. {} changes {:?}", self.reason, self.range.count(), self.range.items()),
98 }
99 }
100}