use crate::rt::CopyValue; use crate::signal::{ReadOnlySignal, Signal, Write}; use std::cell::{Ref, RefMut}; use std::{ fmt::{Debug, Display}, ops::{Add, Div, Mul, Sub}, }; macro_rules! read_impls { ($ty:ident) => { impl Default for $ty { fn default() -> Self { Self::new(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)) } } impl $ty> { /// Read a value from the inner vector. pub fn get(&self, index: usize) -> Option> { Ref::filter_map(self.read(), |v| v.get(index)).ok() } } impl $ty> { /// Unwraps the inner value and clones it. pub fn unwrap(&self) -> T where T: Clone, { self.with(|v| v.clone()).unwrap() } /// Attemps to read the inner value of the Option. pub fn as_ref(&self) -> Option> { Ref::filter_map(self.read(), |v| v.as_ref()).ok() } } }; } macro_rules! write_impls { ($ty:ident) => { impl + Copy + 'static> std::ops::Add for $ty { type Output = T; fn add(self, rhs: T) -> Self::Output { self.with(|v| *v + rhs) } } impl + Copy + 'static> std::ops::AddAssign for $ty { fn add_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v + rhs) } } impl + Copy + 'static> std::ops::SubAssign for $ty { fn sub_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v - rhs) } } impl + Copy + 'static> std::ops::Sub for $ty { type Output = T; fn sub(self, rhs: T) -> Self::Output { self.with(|v| *v - rhs) } } impl + Copy + 'static> std::ops::MulAssign for $ty { fn mul_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v * rhs) } } impl + Copy + 'static> std::ops::Mul for $ty { type Output = T; fn mul(self, rhs: T) -> Self::Output { self.with(|v| *v * rhs) } } impl + Copy + 'static> std::ops::DivAssign for $ty { fn div_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v / rhs) } } impl + Copy + 'static> std::ops::Div for $ty { type Output = T; fn div(self, rhs: T) -> Self::Output { self.with(|v| *v / rhs) } } impl $ty> { /// 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)) } } impl $ty> { /// 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) -> Ref<'_, T> { 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) -> Ref<'_, T> { let borrow = self.read(); if borrow.is_none() { drop(borrow); self.with_mut(|v| *v = Some(default())); Ref::map(self.read(), |v| v.as_ref().unwrap()) } else { Ref::map(borrow, |v| v.as_ref().unwrap()) } } } }; } read_impls!(CopyValue); write_impls!(CopyValue); read_impls!(Signal); write_impls!(Signal); read_impls!(ReadOnlySignal); /// An iterator over the values of a `CopyValue>`. pub struct CopyValueIterator { index: usize, value: CopyValue>, } 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> { type IntoIter = CopyValueIterator; type Item = T; fn into_iter(self) -> Self::IntoIter { CopyValueIterator { index: 0, value: self, } } } impl CopyValue> { /// Write to an element in the inner vector. pub fn get_mut(&self, index: usize) -> Option> { RefMut::filter_map(self.write(), |v| v.get_mut(index)).ok() } } impl CopyValue> { /// Deref the inner value mutably. pub fn as_mut(&self) -> Option> { RefMut::filter_map(self.write(), |v| v.as_mut()).ok() } } /// An iterator over items in a `Signal>`. pub struct SignalIterator { index: usize, value: Signal>, } 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> { type IntoIter = SignalIterator; type Item = T; fn into_iter(self) -> Self::IntoIter { SignalIterator { index: 0, value: self, } } } impl Signal> { /// Returns a reference to an element or `None` if out of bounds. pub fn get_mut(&self, index: usize) -> Option>> { Write::filter_map(self.write(), |v| v.get_mut(index)) } } impl Signal> { /// Returns a reference to an element or `None` if out of bounds. pub fn as_mut(&self) -> Option>> { Write::filter_map(self.write(), |v| v.as_mut()) } }