use crate::line::reactive_graph;
use reactive_graph::computed::{ArcMemo, Memo};
use reactive_graph::graph::Observer;
use reactive_graph::signal::{ArcReadSignal, ArcRwSignal, ReadSignal, RwSignal};
use reactive_graph::traits::{Get, GetUntracked};
use reactive_graph::wrappers::read::{ArcSignal, Signal};
use crate::arg::{ArgSource, ArgValue};
use crate::into_arg::IntoArg;
pub struct SignalArg<S>(S);
impl<S> core::fmt::Debug for SignalArg<S> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("SignalArg(..)")
}
}
impl<S> SignalArg<S> {
pub const fn new(signal: S) -> SignalArg<S> {
SignalArg(signal)
}
}
impl<S> ArgSource for SignalArg<S>
where
S: Get + GetUntracked<Value = <S as Get>::Value> + Send + Sync + 'static,
<S as Get>::Value: Into<ArgValue>,
{
fn arg_value(&self) -> ArgValue {
let value = if Observer::get().is_some() {
self.0.try_get()
} else {
self.0.try_get_untracked()
};
match value {
Some(value) => value.into(),
None => ArgValue::Unset,
}
}
}
struct SignalIntoArg<S>(S);
impl<S> ArgSource for SignalIntoArg<S>
where
S: Get + GetUntracked<Value = <S as Get>::Value> + Send + Sync + 'static,
<S as Get>::Value: IntoArg,
{
fn arg_value(&self) -> ArgValue {
let value = if Observer::get().is_some() {
self.0.try_get()
} else {
self.0.try_get_untracked()
};
match value {
Some(value) => value.into_arg(),
None => ArgValue::Unset,
}
}
}
#[must_use]
pub fn signal_arg<S>(signal: S) -> ArgValue
where
S: Get + GetUntracked<Value = <S as Get>::Value> + Send + Sync + 'static,
<S as Get>::Value: Into<ArgValue>,
{
ArgValue::source(SignalArg::new(signal))
}
macro_rules! signal_arg_from {
($($ty:ident),* $(,)?) => {$(
impl<T> From<$ty<T>> for ArgValue
where
T: Into<ArgValue> + Clone + Send + Sync + 'static,
{
fn from(signal: $ty<T>) -> ArgValue {
signal_arg(signal)
}
}
)*};
}
signal_arg_from!(
Signal,
ReadSignal,
RwSignal,
Memo,
ArcSignal,
ArcReadSignal,
ArcRwSignal,
ArcMemo,
);
macro_rules! signal_into_arg {
($($ty:ident),* $(,)?) => {$(
impl<T> IntoArg for $ty<T>
where
T: IntoArg + Clone + Send + Sync + 'static,
{
fn into_arg(self) -> ArgValue {
ArgValue::source(SignalIntoArg(self))
}
}
)*};
}
signal_into_arg!(
Signal,
ReadSignal,
RwSignal,
Memo,
ArcSignal,
ArcReadSignal,
ArcRwSignal,
ArcMemo,
);