use beet_core::prelude::*;
use beet_dom::prelude::*;
#[derive(Clone)]
pub struct DerivedGetter<T: 'static> {
get_value: CloneFunc<(), T>,
get_bundle: CloneFunc<(), OnSpawn>,
}
impl<T: 'static> DerivedGetter<T> {
pub fn new(
get_value: impl CloneFuncTrait<(), T>,
get_bundle: impl CloneFuncTrait<(), OnSpawn>,
) -> Self {
DerivedGetter {
get_value: CloneFunc::new(get_value),
get_bundle: CloneFunc::new(get_bundle),
}
}
pub fn get(&self) -> T { self.get_value.call_func(()) }
}
impl<T, M> IntoBundle<(Self, M)> for DerivedGetter<T>
where
T: 'static + Send + Sync + IntoBundle<M>,
{
fn into_bundle(self) -> impl Bundle { self.get_bundle.call_func(()) }
}
impl<T: 'static + Send + Clone + std::fmt::Debug> std::fmt::Debug
for DerivedGetter<T>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "DerivedGetter({:?})", self.get())
}
}
impl<T: 'static + Send + Clone + std::fmt::Display> std::fmt::Display
for DerivedGetter<T>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.get().fmt(f)
}
}
pub trait IntoDerivedGetter<T, M> {
fn into_derived_getter(self) -> DerivedGetter<T>;
}
pub struct IntoIntoDerivedGetterMarker;
impl<T, M, U> IntoDerivedGetter<T, (M, IntoIntoDerivedGetterMarker)> for U
where
U: Into<T>,
T: 'static + Send + Sync + Clone + IntoBundle<M>,
{
fn into_derived_getter(self) -> DerivedGetter<T> {
let val = self.into();
let val2 = val.clone();
DerivedGetter::new(
move |_| val.clone(),
move |_| OnSpawn::insert(val2.clone().into_bundle()),
)
}
}
pub struct FuncIntoDerivedGetterMarker;
impl<T, M, F> IntoDerivedGetter<T, (M, FuncIntoDerivedGetterMarker)> for F
where
F: 'static + Send + Sync + Clone + IntoBundle<M> + FnOnce() -> T,
{
fn into_derived_getter(self) -> DerivedGetter<T> {
let self2 = self.clone();
DerivedGetter::new(
move |_| (self.clone())(),
move |_| OnSpawn::insert((self2.clone()).into_bundle()),
)
}
}
#[cfg(test)]
mod test {
use crate::prelude::*;
use beet_core::prelude::*;
#[test]
fn works() {
let (get, set) = signal("foo");
let sig: DerivedGetter<&str> = get.into_derived_getter();
sig.get().xpect_eq("foo");
set("bar");
sig.get().xpect_eq("bar");
}
}