use std::ops::Deref;
use crate::{Component, ComponentSender};
pub struct ObservableVec<T: Clone> {
vec: Vec<T>,
sender: ComponentSender<Self>,
}
impl<T: Clone> ObservableVec<T> {
pub fn push(&mut self, v: T) {
let at = self.vec.len();
self.vec.push(v.clone());
self.sender
.output(ObservableVecEvent::Insert { at, value: v });
}
pub fn insert(&mut self, i: usize, v: T) {
self.vec.insert(i, v.clone());
self.sender
.output(ObservableVecEvent::Insert { at: i, value: v });
}
pub fn pop(&mut self) -> Option<T> {
let res = self.vec.pop();
if let Some(v) = res.clone() {
self.sender.output(ObservableVecEvent::Remove {
at: self.vec.len(),
value: v,
});
}
res
}
pub fn remove(&mut self, i: usize) -> T {
let res = self.vec.remove(i);
self.sender.output(ObservableVecEvent::Remove {
at: i,
value: res.clone(),
});
res
}
pub fn replace(&mut self, i: usize, v: T) -> T {
let element = &mut self.vec[i];
let old = std::mem::replace(element, v.clone());
self.sender.output(ObservableVecEvent::Replace {
at: i,
old: old.clone(),
new: v,
});
old
}
pub fn clear(&mut self) {
self.vec.clear();
self.sender.output(ObservableVecEvent::Clear);
}
pub fn shrink_to_fit(&mut self) {
self.vec.shrink_to_fit();
}
pub fn len(&self) -> usize {
self.vec.len()
}
pub fn is_empty(&self) -> bool {
self.vec.is_empty()
}
pub fn items(&self) -> &[T] {
&self.vec
}
pub fn set_items<U: Into<T>>(
&mut self,
items: impl IntoIterator<Item = U>,
) -> Result<(), std::convert::Infallible> {
self.clear();
for it in items {
self.push(it.into());
}
Ok(())
}
}
impl<T: Clone> Deref for ObservableVec<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.vec
}
}
#[derive(Debug)]
pub enum ObservableVecEvent<T> {
Insert {
at: usize,
value: T,
},
Remove {
at: usize,
value: T,
},
Replace {
at: usize,
old: T,
new: T,
},
Clear,
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ObservableVecMessage {}
impl<T: Clone> Component for ObservableVec<T> {
type Error = std::convert::Infallible;
type Event = ObservableVecEvent<T>;
type Init<'a> = Vec<T>;
type Message = ObservableVecMessage;
async fn init(
init: Self::Init<'_>,
sender: &ComponentSender<Self>,
) -> Result<Self, Self::Error> {
let mut this = Self {
vec: vec![],
sender: sender.clone(),
};
this.set_items(init)?;
Ok(this)
}
}