mirror of
https://github.com/Zenithsiz/dynatos.git
synced 2026-02-04 10:21:23 +00:00
Added initial support for Signal<impl ?Sized>.
This commit is contained in:
parent
c19c2ecddc
commit
4f63e55653
@ -1,5 +1,8 @@
|
||||
//! Reactivity for [`dynatos`]
|
||||
|
||||
// Features
|
||||
#![feature(unsize, coerce_unsized)]
|
||||
|
||||
// Modules
|
||||
pub mod effect;
|
||||
pub mod signal;
|
||||
@ -26,7 +29,7 @@ pub trait SignalGet {
|
||||
/// Signal with
|
||||
pub trait SignalWith {
|
||||
/// Value type
|
||||
type Value;
|
||||
type Value: ?Sized;
|
||||
|
||||
/// Uses the signal value
|
||||
fn with<F, O>(&self, f: F) -> O
|
||||
@ -49,7 +52,7 @@ pub trait SignalReplace<Value> {
|
||||
/// Signal update
|
||||
pub trait SignalUpdate {
|
||||
/// Value type
|
||||
type Value;
|
||||
type Value: ?Sized;
|
||||
|
||||
/// Updates the signal value
|
||||
fn update<F, O>(&self, f: F) -> O
|
||||
|
||||
@ -6,20 +6,23 @@
|
||||
// Imports
|
||||
use {
|
||||
crate::{Effect, SignalGet, SignalReplace, SignalSet, SignalUpdate, SignalWith, Trigger, WeakEffect},
|
||||
std::{cell::RefCell, fmt, mem, rc::Rc},
|
||||
std::{cell::RefCell, fmt, marker::Unsize, mem, ops::CoerceUnsized, rc::Rc},
|
||||
};
|
||||
|
||||
/// Inner
|
||||
struct Inner<T> {
|
||||
/// Value
|
||||
value: RefCell<T>,
|
||||
|
||||
struct Inner<T: ?Sized> {
|
||||
/// Trigger
|
||||
trigger: Trigger,
|
||||
|
||||
/// Value
|
||||
value: RefCell<T>,
|
||||
}
|
||||
|
||||
// TODO: Add `T: ?Sized, U: ?Sized` once `RefCell` supports it.
|
||||
impl<T, U> CoerceUnsized<Inner<U>> for Inner<T> where T: CoerceUnsized<U> {}
|
||||
|
||||
/// Signal
|
||||
pub struct Signal<T> {
|
||||
pub struct Signal<T: ?Sized> {
|
||||
/// Inner
|
||||
inner: Rc<Inner<T>>,
|
||||
}
|
||||
@ -35,6 +38,11 @@ impl<T> Signal<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add `Signal::<dyn Any>::downcast` once we add `{T, U}: ?Sized` to the `CoerceUnsized` impl of `Inner`.
|
||||
// Use `Rc::downcast::<Inner<T>>(self.inner as Rc<dyn Any>)`
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Signal<U>> for Signal<T> where T: Unsize<U> {}
|
||||
|
||||
impl<T> SignalGet for Signal<T>
|
||||
where
|
||||
T: Copy,
|
||||
@ -46,7 +54,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SignalWith for Signal<T> {
|
||||
impl<T: ?Sized> SignalWith for Signal<T> {
|
||||
type Value = T;
|
||||
|
||||
fn with<F, O>(&self, f: F) -> O
|
||||
@ -78,7 +86,7 @@ impl<T> SignalReplace<T> for Signal<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SignalUpdate for Signal<T> {
|
||||
impl<T: ?Sized> SignalUpdate for Signal<T> {
|
||||
type Value = T;
|
||||
|
||||
fn update<F, O>(&self, f: F) -> O
|
||||
|
||||
18
dynatos-reactive/tests/unsized.rs
Normal file
18
dynatos-reactive/tests/unsized.rs
Normal file
@ -0,0 +1,18 @@
|
||||
//! `!Sized` tests.
|
||||
|
||||
// Imports
|
||||
use {
|
||||
dynatos_reactive::{Signal, SignalWith},
|
||||
std::any::Any,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn create_unsized() {
|
||||
let value: i32 = 5;
|
||||
let sig = Signal::<i32>::new(value) as Signal<dyn Any>;
|
||||
|
||||
sig.with(|dyn_value| {
|
||||
assert_eq!(dyn_value.type_id(), value.type_id());
|
||||
assert_eq!(dyn_value.downcast_ref::<i32>(), Some(&value))
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user