use alloc::rc::Rc;
use alloc::sync::Arc;
use core::fmt;
use crate::{Filter, Gate, IntoListener};
#[cfg(doc)]
use crate::{Flag, FlagListener, Notifier, Store, StoreLock, StoreRef};
#[cfg_attr(not(feature = "std-sync"), allow(rustdoc::broken_intra_doc_links))]
pub trait Listener<M>: fmt::Debug {
fn receive(&self, messages: &[M]) -> bool;
#[doc(hidden)]
fn into_dyn_listener_unsync(self) -> crate::unsync::DynListener<M>
where
Self: Sized + 'static,
{
Rc::new(self)
}
#[doc(hidden)]
fn into_dyn_listener_sync(self) -> crate::sync::DynListener<M>
where
Self: Sized + Send + Sync + 'static,
{
Arc::new(self)
}
fn filter<MI, F>(self, function: F) -> Filter<F, Self, 1>
where
Self: Sized,
F: for<'a> Fn(&'a MI) -> Option<M>,
{
Filter {
function,
target: self,
}
}
fn gate(self) -> (Gate, crate::GateListener<Self>)
where
Self: Sized,
{
Gate::new(self)
}
}
pub trait Listen {
type Msg;
type Listener: Listener<Self::Msg>;
fn listen<L>(&self, listener: L)
where
L: IntoListener<Self::Listener, Self::Msg>,
Self: Sized,
{
self.listen_raw(listener.into_listener())
}
fn listen_raw(&self, listener: Self::Listener);
}
impl<T: ?Sized + Listen> Listen for &T {
type Msg = T::Msg;
type Listener = T::Listener;
fn listen_raw(&self, listener: Self::Listener) {
(**self).listen_raw(listener)
}
}
impl<T: ?Sized + Listen> Listen for &mut T {
type Msg = T::Msg;
type Listener = T::Listener;
fn listen_raw(&self, listener: Self::Listener) {
(**self).listen_raw(listener)
}
}
impl<T: ?Sized + Listen> Listen for alloc::boxed::Box<T> {
type Msg = T::Msg;
type Listener = T::Listener;
fn listen_raw(&self, listener: Self::Listener) {
(**self).listen_raw(listener)
}
}
impl<T: ?Sized + Listen> Listen for alloc::rc::Rc<T> {
type Msg = T::Msg;
type Listener = T::Listener;
fn listen_raw(&self, listener: Self::Listener) {
(**self).listen_raw(listener)
}
}
impl<T: ?Sized + Listen> Listen for alloc::sync::Arc<T> {
type Msg = T::Msg;
type Listener = T::Listener;
fn listen_raw(&self, listener: Self::Listener) {
(**self).listen_raw(listener)
}
}