Skip to main content

ferroui_dynamic_data/list/
source_list_edit_convenience_ex.rs

1//! `SourceListEditConvenienceEx` (`List/SourceListEditConvenienceEx.cs`): the edits of one step of
2//! source lists.
3
4use super::internal::edit_diff;
5use super::{remove_many, replace, IExtendedList, IList, ISourceList};
6
7/// The edit conveniences of source lists (`SourceListEditConvenienceEx`), implemented for every
8/// source list.
9pub trait SourceListEditConvenienceEx<T: Clone + PartialEq + 'static>: ISourceList<T> {
10    /// Adds `item` (`Add`).
11    fn add(&self, item: T) {
12        let mut item = Some(item);
13        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| {
14            if let Some(item) = item.take() {
15                IList::add(list, item);
16            }
17        });
18    }
19
20    /// Adds the items (`AddRange`).
21    fn add_range(&self, items: impl IntoIterator<Item = T>) {
22        let mut items = Some(items.into_iter().collect::<Vec<T>>());
23        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| {
24            if let Some(items) = items.take() {
25                IList::add_range(list, items);
26            }
27        });
28    }
29
30    /// Removes every item (`Clear`).
31    fn clear(&self) {
32        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| IList::clear(list));
33    }
34
35    /// Makes the list hold `all_items` with the fewest changes, items compared by `PartialEq`
36    /// (`EditDiff(IEnumerable<T>, IEqualityComparer<T>? = null)`).
37    fn edit_diff(&self, all_items: impl IntoIterator<Item = T>) {
38        edit_diff(self, all_items.into_iter().collect(), &|a: &T, b: &T| a == b);
39    }
40
41    /// [`edit_diff`](Self::edit_diff) with the equality of `equality_comparer`
42    /// (`EditDiff(IEnumerable<T>, IEqualityComparer<T>)`).
43    fn edit_diff_with_comparer(&self, all_items: impl IntoIterator<Item = T>, equality_comparer: impl Fn(&T, &T) -> bool) {
44        edit_diff(self, all_items.into_iter().collect(), &equality_comparer);
45    }
46
47    /// Inserts `item` at `index` (`Insert`).
48    fn insert(&self, index: usize, item: T) {
49        let mut item = Some(item);
50        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| {
51            if let Some(item) = item.take() {
52                IList::insert(list, index, item);
53            }
54        });
55    }
56
57    /// Inserts the items at `index` (`InsertRange`, `ListEx.AddRange(items, index)`).
58    fn insert_range(&self, items: impl IntoIterator<Item = T>, index: usize) {
59        let mut items = Some(items.into_iter().collect::<Vec<T>>());
60        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| {
61            if let Some(items) = items.take() {
62                list.insert_range(items, index);
63            }
64        });
65    }
66
67    /// Moves the item at `original` to `destination` (`Move`; `move` is a keyword of Rust).
68    fn move_item(&self, original: usize, destination: usize) {
69        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| list.move_index(original, destination));
70    }
71
72    /// Removes the first item equal to `item`; whether there was one (`Remove`).
73    fn remove(&self, item: &T) -> bool {
74        let mut removed = false;
75        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| removed = IList::remove(list, item));
76        removed
77    }
78
79    /// Removes the item at `index` (`RemoveAt`).
80    fn remove_at(&self, index: usize) {
81        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| IList::remove_at(list, index));
82    }
83
84    /// Removes the items (`RemoveMany`).
85    fn remove_many(&self, items_to_remove: impl IntoIterator<Item = T>) {
86        let items: Vec<T> = items_to_remove.into_iter().collect();
87        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| {
88            let list: &mut dyn IList<T> = list;
89            remove_many(list, &items);
90        });
91    }
92
93    /// Removes `count` items from `index` (`RemoveRange`).
94    fn remove_range(&self, index: usize, count: usize) {
95        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| IList::remove_range(list, index, count));
96    }
97
98    /// Replaces `original` with `destination` (`Replace`).
99    ///
100    /// # Panics
101    /// When `original` is not in the list (`ArgumentException`).
102    fn replace(&self, original: &T, destination: T) {
103        let mut destination = Some(destination);
104        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| {
105            if let Some(destination) = destination.take() {
106                let list: &mut dyn IList<T> = list;
107                replace(list, original, destination);
108            }
109        });
110    }
111
112    /// Replaces the item at `index` with `item` (`ReplaceAt`).
113    fn replace_at(&self, index: usize, item: T) {
114        let mut item = Some(item);
115        self.edit_dyn(&mut |list: &mut dyn IExtendedList<T>| {
116            if let Some(item) = item.take() {
117                IList::set(list, index, item);
118            }
119        });
120    }
121}
122
123impl<T: Clone + PartialEq + 'static, L: ISourceList<T> + ?Sized> SourceListEditConvenienceEx<T> for L {}