Skip to main content

winio_elm/
collection.rs

1use std::ops::Deref;
2
3use crate::{Component, ComponentSender};
4
5/// An observable vector. It outputs events after being changed.
6pub struct ObservableVec<T: Clone> {
7    vec: Vec<T>,
8    sender: ComponentSender<Self>,
9}
10
11impl<T: Clone> ObservableVec<T> {
12    /// Appends an element to the back of a collection.
13    pub fn push(&mut self, v: T) {
14        let at = self.vec.len();
15        self.vec.push(v.clone());
16        self.sender
17            .output(ObservableVecEvent::Insert { at, value: v });
18    }
19
20    /// Inserts an element at specified position.
21    pub fn insert(&mut self, i: usize, v: T) {
22        self.vec.insert(i, v.clone());
23        self.sender
24            .output(ObservableVecEvent::Insert { at: i, value: v });
25    }
26
27    /// Removes the last element.
28    pub fn pop(&mut self) -> Option<T> {
29        let res = self.vec.pop();
30        if let Some(v) = res.clone() {
31            self.sender.output(ObservableVecEvent::Remove {
32                at: self.vec.len(),
33                value: v,
34            });
35        }
36        res
37    }
38
39    /// Removes and returns the element at specified position.
40    pub fn remove(&mut self, i: usize) -> T {
41        let res = self.vec.remove(i);
42        self.sender.output(ObservableVecEvent::Remove {
43            at: i,
44            value: res.clone(),
45        });
46        res
47    }
48
49    /// Replaces the element at specified position, and return the old value.
50    pub fn replace(&mut self, i: usize, v: T) -> T {
51        let element = &mut self.vec[i];
52        let old = std::mem::replace(element, v.clone());
53        self.sender.output(ObservableVecEvent::Replace {
54            at: i,
55            old: old.clone(),
56            new: v,
57        });
58        old
59    }
60
61    /// Clears the vector.
62    pub fn clear(&mut self) {
63        self.vec.clear();
64        self.sender.output(ObservableVecEvent::Clear);
65    }
66
67    /// Shrinks the capacity of the vector as much as possible.
68    pub fn shrink_to_fit(&mut self) {
69        self.vec.shrink_to_fit();
70    }
71
72    /// Length of the vector.
73    pub fn len(&self) -> usize {
74        self.vec.len()
75    }
76
77    /// Checks if the vector is empty.
78    pub fn is_empty(&self) -> bool {
79        self.vec.is_empty()
80    }
81
82    /// Gets the inner items.
83    pub fn items(&self) -> &[T] {
84        &self.vec
85    }
86
87    /// Clears the vector, and appends the items one by one.
88    pub fn set_items<U: Into<T>>(
89        &mut self,
90        items: impl IntoIterator<Item = U>,
91    ) -> Result<(), std::convert::Infallible> {
92        self.clear();
93        for it in items {
94            self.push(it.into());
95        }
96        Ok(())
97    }
98}
99
100impl<T: Clone> Deref for ObservableVec<T> {
101    type Target = [T];
102
103    fn deref(&self) -> &Self::Target {
104        &self.vec
105    }
106}
107
108/// The events of [`ObservableVec`].
109#[derive(Debug)]
110pub enum ObservableVecEvent<T> {
111    /// An element inserted.
112    Insert {
113        /// The insert position.
114        at: usize,
115        /// The value.
116        value: T,
117    },
118    /// An element removed.
119    Remove {
120        /// The remove position
121        at: usize,
122        /// The value.
123        value: T,
124    },
125    /// An element of specific position is replaced.
126    Replace {
127        /// The replace position.
128        at: usize,
129        /// The old value.
130        old: T,
131        /// The new value.
132        new: T,
133    },
134    /// The vector has been cleared.
135    Clear,
136}
137
138/// The messages of [`ObservableVec`].
139#[derive(Debug)]
140#[non_exhaustive]
141pub enum ObservableVecMessage {}
142
143impl<T: Clone> Component for ObservableVec<T> {
144    type Error = std::convert::Infallible;
145    type Event = ObservableVecEvent<T>;
146    type Init<'a> = Vec<T>;
147    type Message = ObservableVecMessage;
148
149    async fn init(
150        init: Self::Init<'_>,
151        sender: &ComponentSender<Self>,
152    ) -> Result<Self, Self::Error> {
153        let mut this = Self {
154            vec: vec![],
155            sender: sender.clone(),
156        };
157        this.set_items(init)?;
158        Ok(this)
159    }
160}