use crate::rt::CopyValue; use crate::signal::{ReadOnlySignal, Signal, Write}; use crate::SignalData; use generational_box::Mappable; use generational_box::{MappableMut, Storage}; use std::{ fmt::{Debug, Display}, ops::{Add, Div, Mul, Sub}, }; macro_rules! read_impls { ($ty:ident, $bound:path) => { impl Default for $ty { fn default() -> Self { Self::new_maybe_sync(Default::default()) } } impl std::clone::Clone for $ty { fn clone(&self) -> Self { *self } } impl Copy for $ty {} impl Display for $ty { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Display::fmt(v, f)) } } impl Debug for $ty { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Debug::fmt(v, f)) } } }; } macro_rules! write_impls { ($ty:ident, $bound:path, $vec_bound:path) => { impl + Copy + 'static, S: $bound> std::ops::Add for $ty { type Output = T; fn add(self, rhs: T) -> Self::Output { self.with(|v| *v + rhs) } } impl + Copy + 'static, S: $bound> std::ops::AddAssign for $ty { fn add_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v + rhs) } } impl + Copy + 'static, S: $bound> std::ops::SubAssign for $ty { fn sub_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v - rhs) } } impl + Copy + 'static, S: $bound> std::ops::Sub for $ty { type Output = T; fn sub(self, rhs: T) -> Self::Output { self.with(|v| *v - rhs) } } impl + Copy + 'static, S: $bound> std::ops::MulAssign for $ty { fn mul_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v * rhs) } } impl + Copy + 'static, S: $bound> std::ops::Mul for $ty { type Output = T; fn mul(self, rhs: T) -> Self::Output { self.with(|v| *v * rhs) } } impl + Copy + 'static, S: $bound> std::ops::DivAssign for $ty { fn div_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v / rhs) } } impl + Copy + 'static, S: $bound> std::ops::Div for $ty { type Output = T; fn div(self, rhs: T) -> Self::Output { self.with(|v| *v / rhs) } } impl $ty, S> { /// Pushes a new value to the end of the vector. pub fn push(&self, value: T) { self.with_mut(|v| v.push(value)) } /// Pops the last value from the vector. pub fn pop(&self) -> Option { self.with_mut(|v| v.pop()) } /// Inserts a new value at the given index. pub fn insert(&self, index: usize, value: T) { self.with_mut(|v| v.insert(index, value)) } /// Removes the value at the given index. pub fn remove(&self, index: usize) -> T { self.with_mut(|v| v.remove(index)) } /// Clears the vector, removing all values. pub fn clear(&self) { self.with_mut(|v| v.clear()) } /// Extends the vector with the given iterator. pub fn extend(&self, iter: impl IntoIterator) { self.with_mut(|v| v.extend(iter)) } /// Truncates the vector to the given length. pub fn truncate(&self, len: usize) { self.with_mut(|v| v.truncate(len)) } /// Swaps two values in the vector. pub fn swap_remove(&self, index: usize) -> T { self.with_mut(|v| v.swap_remove(index)) } /// Retains only the values that match the given predicate. pub fn retain(&self, f: impl FnMut(&T) -> bool) { self.with_mut(|v| v.retain(f)) } /// Splits the vector into two at the given index. pub fn split_off(&self, at: usize) -> Vec { self.with_mut(|v| v.split_off(at)) } } }; } read_impls!(CopyValue, Storage); impl>> CopyValue, S> { /// Read a value from the inner vector. pub fn get(&self, index: usize) -> Option<>>::Mapped> { S::Ref::try_map(self.read(), move |v| v.get(index)) } } impl>> CopyValue, S> { /// Unwraps the inner value and clones it. pub fn unwrap(&self) -> T where T: Clone, { self.with(|v| v.clone()).unwrap() } /// Attempts to read the inner value of the Option. pub fn as_ref(&self) -> Option<>>::Mapped> { S::Ref::try_map(self.read(), |v| v.as_ref()) } } write_impls!(CopyValue, Storage, Storage>); impl>> CopyValue, S> { /// Takes the value out of the Option. pub fn take(&self) -> Option { self.with_mut(|v| v.take()) } /// Replace the value in the Option. pub fn replace(&self, value: T) -> Option { self.with_mut(|v| v.replace(value)) } /// Gets the value out of the Option, or inserts the given value if the Option is empty. pub fn get_or_insert(&self, default: T) -> >>::Mapped { self.get_or_insert_with(|| default) } /// Gets the value out of the Option, or inserts the value returned by the given function if the Option is empty. pub fn get_or_insert_with( &self, default: impl FnOnce() -> T, ) -> >>::Mapped { let borrow = self.read(); if borrow.is_none() { drop(borrow); self.with_mut(|v| *v = Some(default())); S::Ref::map(self.read(), |v| v.as_ref().unwrap()) } else { S::Ref::map(borrow, |v| v.as_ref().unwrap()) } } } read_impls!(Signal, Storage>); impl>>> Signal, S> { /// Read a value from the inner vector. pub fn get( &self, index: usize, ) -> Option< <<>>>::Ref as Mappable>>>::Mapped> as Mappable< Vec, >>::Mapped, >{ <>>>::Ref as Mappable>>>::Mapped::>::try_map(self.read(), move |v| v.get(index)) } } impl>>> Signal, S> { /// Unwraps the inner value and clones it. pub fn unwrap(&self) -> T where T: Clone, { self.with(|v| v.clone()).unwrap() } /// Attempts to read the inner value of the Option. pub fn as_ref( &self, ) -> Option< <<>>>::Ref as Mappable>>>::Mapped< Option, > as Mappable>>::Mapped, > { <>>>::Ref as Mappable>>>::Mapped::< Option, >::try_map(self.read(), |v| v.as_ref()) } } write_impls!(Signal, Storage>, Storage>>); impl>>> Signal, S> { /// Takes the value out of the Option. pub fn take(&self) -> Option { self.with_mut(|v| v.take()) } /// Replace the value in the Option. pub fn replace(&self, value: T) -> Option { self.with_mut(|v| v.replace(value)) } /// Gets the value out of the Option, or inserts the given value if the Option is empty. pub fn get_or_insert(&self, default: T) -> <>>>::Mapped> as Mappable>>::Mapped{ self.get_or_insert_with(|| default) } /// Gets the value out of the Option, or inserts the value returned by the given function if the Option is empty. pub fn get_or_insert_with( &self, default: impl FnOnce() -> T, ) -><>>>::Mapped> as Mappable>>::Mapped{ let borrow = self.read(); if borrow.is_none() { drop(borrow); self.with_mut(|v| *v = Some(default())); >>>::Mapped::>::map( self.read(), |v| v.as_ref().unwrap(), ) } else { >>>::Mapped::>::map(borrow, |v| { v.as_ref().unwrap() }) } } } read_impls!(ReadOnlySignal, Storage>); /// An iterator over the values of a `CopyValue>`. pub struct CopyValueIterator>> { index: usize, value: CopyValue, S>, } impl>> Iterator for CopyValueIterator { type Item = T; fn next(&mut self) -> Option { let index = self.index; self.index += 1; self.value.get(index).map(|v| v.clone()) } } impl>> IntoIterator for CopyValue, S> { type IntoIter = CopyValueIterator; type Item = T; fn into_iter(self) -> Self::IntoIter { CopyValueIterator { index: 0, value: self, } } } impl>> CopyValue, S> { /// Write to an element in the inner vector. pub fn get_mut(&self, index: usize) -> Option<>>::Mapped> { S::Mut::try_map(self.write(), |v: &mut Vec| v.get_mut(index)) } } impl>> CopyValue, S> { /// Deref the inner value mutably. pub fn as_mut( &self, ) -> Option<<>>::Mut as MappableMut>>::Mapped> { S::Mut::try_map(self.write(), |v: &mut Option| v.as_mut()) } } /// An iterator over items in a `Signal>`. pub struct SignalIterator>>> { index: usize, value: Signal, S>, } impl>>> Iterator for SignalIterator { type Item = T; fn next(&mut self) -> Option { let index = self.index; self.index += 1; self.value.get(index).map(|v| v.clone()) } } impl>>> IntoIterator for Signal, S> { type IntoIter = SignalIterator; type Item = T; fn into_iter(self) -> Self::IntoIter { SignalIterator { index: 0, value: self, } } } impl>>> Signal, S> where <>>>::Mut as MappableMut< SignalData>, >>::Mapped>: MappableMut>, { /// Returns a reference to an element or `None` if out of bounds. pub fn get_mut( &self, index: usize, ) -> Option< Write< T, <<>>>::Mut as MappableMut>>>::Mapped< Vec, > as MappableMut>>::Mapped, S, Vec, >, > { Write::filter_map(self.write(), |v| v.get_mut(index)) } } impl>>> Signal, S> { /// Returns a reference to an element or `None` if out of bounds. pub fn as_mut(&self) -> Option>>>::Mut as MappableMut>>>::Mapped> as MappableMut>>::Mapped, S, Option>>{ Write::filter_map(self.write(), |v| v.as_mut()) } }