Moved all signal operators to their own module.

This commit is contained in:
2024-03-05 14:57:06 +00:00
parent e87bf87157
commit 430d7dea10
3 changed files with 155 additions and 127 deletions

View File

@@ -14,7 +14,18 @@ pub mod with_default;
pub use self::{
derived::Derived,
effect::{Effect, WeakEffect},
signal::Signal,
signal::{
Signal,
SignalGet,
SignalGetClone,
SignalGetCloned,
SignalGetCopy,
SignalReplace,
SignalSet,
SignalSetWith,
SignalUpdate,
SignalWith,
},
trigger::Trigger,
with_default::{SignalWithDefault, WithDefault},
};
@@ -22,130 +33,6 @@ pub use self::{
// Imports
use std::marker::Unsize;
/// Types which may be copied by [`SignalGet`]
pub trait SignalGetCopy<T>: Sized {
fn copy(self) -> T;
}
impl<T: Copy> SignalGetCopy<T> for &'_ T {
fn copy(self) -> T {
*self
}
}
impl<T: Copy> SignalGetCopy<Option<T>> for Option<&'_ T> {
fn copy(self) -> Option<T> {
self.copied()
}
}
/// Signal get
pub trait SignalGet<T> {
/// Gets the signal value, by copying it.
fn get(&self) -> T;
}
impl<S, T> SignalGet<T> for S
where
S: SignalWith,
for<'a> S::Value<'a>: SignalGetCopy<T>,
{
fn get(&self) -> T {
self.with(|value| value.copy())
}
}
/// Types which may be cloned by [`SignalGetCloned`]
pub trait SignalGetClone<T>: Sized {
fn clone(self) -> T;
}
impl<T: Clone> SignalGetClone<T> for &'_ T {
fn clone(self) -> T {
self.clone()
}
}
impl<T: Clone> SignalGetClone<Option<T>> for Option<&'_ T> {
fn clone(self) -> Option<T> {
self.cloned()
}
}
/// Signal cloned
pub trait SignalGetCloned<T> {
/// Gets the signal value, by cloning it.
fn get_cloned(&self) -> T;
}
impl<S, T> SignalGetCloned<T> for S
where
S: SignalWith,
for<'a> S::Value<'a>: SignalGetClone<T>,
{
fn get_cloned(&self) -> T {
self.with(|value| value.clone())
}
}
/// Signal with
pub trait SignalWith {
/// Value type
type Value<'a>: ?Sized;
/// Uses the signal value
fn with<F, O>(&self, f: F) -> O
where
F: for<'a> FnOnce(Self::Value<'a>) -> O;
}
/// Types which may be set by [`SignalSet`]
pub trait SignalSetWith<T>: Sized {
fn set(self, new_value: T);
}
impl<T> SignalSetWith<T> for &'_ mut T {
fn set(self, new_value: T) {
*self = new_value;
}
}
impl<T> SignalSetWith<T> for &'_ mut Option<T> {
fn set(self, new_value: T) {
*self = Some(new_value);
}
}
/// Signal set
pub trait SignalSet<Value> {
/// Sets the signal value
fn set(&self, new_value: Value);
}
impl<S, T> SignalSet<T> for S
where
S: SignalUpdate,
for<'a> S::Value<'a>: SignalSetWith<T>,
{
fn set(&self, new_value: T) {
self.update(|value| SignalSetWith::set(value, new_value));
}
}
/// Signal replace
pub trait SignalReplace<Value> {
/// Replaces the signal value, returning the previous value
fn replace(&self, new_value: Value) -> Value;
}
/// Signal update
pub trait SignalUpdate {
/// Value type
type Value<'a>: ?Sized;
/// Updates the signal value
fn update<F, O>(&self, f: F) -> O
where
F: for<'a> FnOnce(Self::Value<'a>) -> O;
}
/// Types that may be converted into a subscriber
pub trait IntoSubscriber {
/// Converts this type into a weak effect.

View File

@@ -3,9 +3,25 @@
//! A read-write value that automatically updates
//! any subscribers when changed.
// Modules
pub mod ops;
// Exports
pub use ops::{
SignalGet,
SignalGetClone,
SignalGetCloned,
SignalGetCopy,
SignalReplace,
SignalSet,
SignalSetWith,
SignalUpdate,
SignalWith,
};
// Imports
use {
crate::{effect, SignalReplace, SignalUpdate, SignalWith, Trigger},
crate::{effect, Trigger},
std::{cell::RefCell, fmt, marker::Unsize, mem, ops::CoerceUnsized, rc::Rc},
};
@@ -121,7 +137,7 @@ mod test {
let signals = std::array::from_fn::<_, 100, _>(|_| Signal::new(0_i32));
bencher.iter(|| {
for signal in &signals {
let signal = test::black_box(signal.clone());
let signal = test::black_box(Signal::clone(signal));
mem::forget(signal);
}
});

View File

@@ -0,0 +1,125 @@
//! Signal operators
/// Types which may be copied by [`SignalGet`]
pub trait SignalGetCopy<T>: Sized {
fn copy(self) -> T;
}
impl<T: Copy> SignalGetCopy<T> for &'_ T {
fn copy(self) -> T {
*self
}
}
impl<T: Copy> SignalGetCopy<Option<T>> for Option<&'_ T> {
fn copy(self) -> Option<T> {
self.copied()
}
}
/// Signal get
pub trait SignalGet<T> {
/// Gets the signal value, by copying it.
fn get(&self) -> T;
}
impl<S, T> SignalGet<T> for S
where
S: SignalWith,
for<'a> S::Value<'a>: SignalGetCopy<T>,
{
fn get(&self) -> T {
self.with(|value| value.copy())
}
}
/// Types which may be cloned by [`SignalGetCloned`]
pub trait SignalGetClone<T>: Sized {
fn clone(self) -> T;
}
impl<T: Clone> SignalGetClone<T> for &'_ T {
fn clone(self) -> T {
self.clone()
}
}
impl<T: Clone> SignalGetClone<Option<T>> for Option<&'_ T> {
fn clone(self) -> Option<T> {
self.cloned()
}
}
/// Signal cloned
pub trait SignalGetCloned<T> {
/// Gets the signal value, by cloning it.
fn get_cloned(&self) -> T;
}
impl<S, T> SignalGetCloned<T> for S
where
S: SignalWith,
for<'a> S::Value<'a>: SignalGetClone<T>,
{
fn get_cloned(&self) -> T {
self.with(|value| value.clone())
}
}
/// Signal with
pub trait SignalWith {
/// Value type
type Value<'a>: ?Sized;
/// Uses the signal value
fn with<F, O>(&self, f: F) -> O
where
F: for<'a> FnOnce(Self::Value<'a>) -> O;
}
/// Types which may be set by [`SignalSet`]
pub trait SignalSetWith<T>: Sized {
fn set(self, new_value: T);
}
impl<T> SignalSetWith<T> for &'_ mut T {
fn set(self, new_value: T) {
*self = new_value;
}
}
impl<T> SignalSetWith<T> for &'_ mut Option<T> {
fn set(self, new_value: T) {
*self = Some(new_value);
}
}
/// Signal set
pub trait SignalSet<Value> {
/// Sets the signal value
fn set(&self, new_value: Value);
}
impl<S, T> SignalSet<T> for S
where
S: SignalUpdate,
for<'a> S::Value<'a>: SignalSetWith<T>,
{
fn set(&self, new_value: T) {
self.update(|value| SignalSetWith::set(value, new_value));
}
}
/// Signal replace
pub trait SignalReplace<Value> {
/// Replaces the signal value, returning the previous value
fn replace(&self, new_value: Value) -> Value;
}
/// Signal update
pub trait SignalUpdate {
/// Value type
type Value<'a>: ?Sized;
/// Updates the signal value
fn update<F, O>(&self, f: F) -> O
where
F: for<'a> FnOnce(Self::Value<'a>) -> O;
}