use core::fmt;
use core::marker::PhantomData;
use alloc::sync::Arc;
#[cfg(doc)]
use crate::Notifier;
use crate::{FromListener, IntoListener, Listen, Listener};
mod flatten;
pub use flatten::Flatten;
mod map;
pub use map::Map;
pub trait Source: Listen<Msg = ()> + fmt::Debug {
type Value;
#[must_use]
fn get(&self) -> Self::Value;
fn map<F, O>(self, function: F) -> Map<Self, F>
where
Self: Sized,
F: Fn(Self::Value) -> O,
{
Map {
source: self,
function,
}
}
fn flatten(self) -> Flatten<Self>
where
Self: Sized,
Self::Value: Source + Clone,
Self::Listener: FromListener<flatten::OuterListener<Self>, ()>,
<Self::Value as Listen>::Listener: FromListener<flatten::InnerListener<Self>, ()>,
{
Flatten::new(self)
}
}
impl<T: ?Sized + Source> Source for &T {
type Value = T::Value;
fn get(&self) -> Self::Value {
T::get(*self)
}
}
impl<T: ?Sized + Source> Source for &mut T {
type Value = T::Value;
fn get(&self) -> Self::Value {
T::get(*self)
}
}
impl<T: ?Sized + Source> Source for alloc::boxed::Box<T> {
type Value = T::Value;
fn get(&self) -> Self::Value {
T::get(&**self)
}
}
impl<T: ?Sized + Source> Source for alloc::rc::Rc<T> {
type Value = T::Value;
fn get(&self) -> Self::Value {
T::get(&**self)
}
}
impl<T: ?Sized + Source> Source for alloc::sync::Arc<T> {
type Value = T::Value;
fn get(&self) -> Self::Value {
T::get(&**self)
}
}
pub struct Constant<T, L> {
value: T,
_phantom: PhantomData<fn(L)>,
}
impl<T, L> Constant<T, L> {
pub const fn new(value: T) -> Self {
Self {
value,
_phantom: PhantomData,
}
}
pub fn into_inner(self) -> T {
self.value
}
}
impl<T, L: Listener<()>> Listen for Constant<T, L> {
type Msg = ();
type Listener = L;
fn listen<L2: IntoListener<L, ()>>(&self, _: L2) {
}
fn listen_raw(&self, _: Self::Listener) {}
}
impl<T: Clone + fmt::Debug, L: Listener<()>> Source for Constant<T, L> {
type Value = T;
fn get(&self) -> Self::Value {
self.value.clone()
}
}
impl<T: fmt::Debug, L> core::fmt::Debug for Constant<T, L> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Constant").field(&self.value).finish()
}
}
impl<T: Copy, L> Copy for Constant<T, L> {}
impl<T: Clone, L> Clone for Constant<T, L> {
fn clone(&self) -> Self {
Self {
value: self.value.clone(),
_phantom: PhantomData,
}
}
}
impl<T: Eq, L> Eq for Constant<T, L> {}
impl<T: PartialEq, L> PartialEq for Constant<T, L> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: core::hash::Hash, L> core::hash::Hash for Constant<T, L> {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.value.hash(state);
}
}
impl<T: Ord, L> Ord for Constant<T, L> {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.value.cmp(&other.value)
}
}
impl<T: PartialOrd, L> PartialOrd for Constant<T, L> {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
self.value.partial_cmp(&other.value)
}
}
impl<T: Default, L> Default for Constant<T, L> {
fn default() -> Self {
Self {
value: Default::default(),
_phantom: PhantomData,
}
}
}
impl<T, L> AsRef<T> for Constant<T, L> {
fn as_ref(&self) -> &T {
&self.value
}
}
impl<T, L> core::borrow::Borrow<T> for Constant<T, L> {
fn borrow(&self) -> &T {
&self.value
}
}
impl<T, L> From<T> for Constant<T, L> {
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<T> From<Constant<T, crate::unsync::DynListener<()>>> for crate::unsync::DynSource<T>
where
T: Clone + fmt::Debug + 'static,
{
fn from(value: Constant<T, crate::unsync::DynListener<()>>) -> Self {
Arc::new(value)
}
}
impl<T> From<Constant<T, crate::sync::DynListener<()>>> for crate::sync::DynSource<T>
where
T: Clone + fmt::Debug + Send + Sync + 'static,
{
fn from(value: Constant<T, crate::sync::DynListener<()>>) -> Self {
Arc::new(value)
}
}