use { crate::{ view::{InnerViewPort, OuterViewPort, View, ViewPort}, }, std::sync::RwLock, std::{ ops::{Deref, DerefMut}, sync::Arc, }, }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> use serde::{Deserialize, Serialize}; #[derive(Clone, Serialize, Deserialize)] pub enum VecDiff { Clear, Push(T), Remove(usize), Insert { idx: usize, val: T }, Update { idx: usize, val: T }, } impl View for Vec where T: Clone + Send + Sync + 'static, { type Msg = VecDiff; } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] pub struct VecBuffer where T: Clone + Send + Sync + 'static, { data: Arc>>, port: InnerViewPort>> } impl VecBuffer where T: Clone + Send + Sync + 'static, { pub fn with_data_port(data: Vec, port: InnerViewPort>>) -> Self { let data = Arc::new(RwLock::new(data)); port.set_view(Some(data.clone())); for x in data.read().unwrap().iter().cloned() { port.notify(&VecDiff::Push(x)); } VecBuffer { data, port } } pub fn with_data(data: Vec) -> Self { VecBuffer::with_data_port(data, ViewPort::new().into_inner()) } pub fn with_port(port: InnerViewPort>>) -> Self { VecBuffer::with_data_port(vec![], port) } pub fn new() -> Self { VecBuffer::with_port(ViewPort::new().into_inner()) } pub fn get_port(&self) -> OuterViewPort>> { self.port.0.outer() } pub fn apply_diff(&mut self, diff: VecDiff) { let mut data = self.data.write().unwrap(); match &diff { VecDiff::Clear => { data.clear(); } VecDiff::Push(val) => { data.push(val.clone()); } VecDiff::Remove(idx) => { data.remove(*idx); } VecDiff::Insert { idx, val } => { data.insert(*idx, val.clone()); } VecDiff::Update { idx, val } => { data[*idx] = val.clone(); } } drop(data); self.port.notify(&diff); } pub fn len(&self) -> usize { self.data.read().unwrap().len() } pub fn get(&self, idx: usize) -> T { self.data.read().unwrap()[idx].clone() } pub fn clear(&mut self) { self.apply_diff(VecDiff::Clear); } pub fn push(&mut self, val: T) { self.apply_diff(VecDiff::Push(val)); } pub fn remove(&mut self, idx: usize) { self.apply_diff(VecDiff::Remove(idx)); } pub fn insert(&mut self, idx: usize, val: T) { self.apply_diff(VecDiff::Insert { idx, val }); } pub fn update(&mut self, idx: usize, val: T) { self.apply_diff(VecDiff::Update { idx, val }); } pub fn get_mut(&mut self, idx: usize) -> MutableVecAccess { MutableVecAccess { buf: self.clone(), idx, val: self.get(idx), } } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct MutableVecAccess where T: Clone + Send + Sync + 'static, { buf: VecBuffer, idx: usize, val: T, } impl Deref for MutableVecAccess where T: Clone + Send + Sync + 'static, { type Target = T; fn deref(&self) -> &T { &self.val } } impl DerefMut for MutableVecAccess where T: Clone + Send + Sync + 'static, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.val } } impl Drop for MutableVecAccess where T: Clone + Send + Sync + 'static, { fn drop(&mut self) { self.buf.update(self.idx, self.val.clone()); } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[cfg(test)] mod tests { use crate::buffer::vec::*; #[test] fn vec_buffer1() { let mut buffer = VecBuffer::new(); buffer.push('a'); buffer.push('b'); buffer.push('c'); } }