use super::ref_count::RefCount;
use crate::disposable::Disposable;
use crate::observable::{Observable, Subscription};
use crate::observer::Observer;
use crate::subject::subject_observable::SubjectObservable;
use crate::utils::types::MaybeSend;
use educe::Educe;
#[derive(Debug, Clone, Copy, Default)]
pub struct Disconnected;
#[derive(Educe)]
#[educe(Debug)]
pub struct Connected<D: Disposable>(Subscription<D>);
#[derive(Educe)]
#[educe(Debug)]
pub struct ConnectableController<OE, S, State = Disconnected> {
source: OE,
subject: S,
state: State,
}
impl<OE, S> ConnectableController<OE, S, Disconnected> {
pub fn new(source: OE, subject: S) -> Self {
Self {
source,
subject,
state: Disconnected,
}
}
#[must_use = "the returned controller owns the source connection"]
pub fn connect<'or, T, E>(self) -> ConnectableController<OE, S, Connected<OE::D>>
where
OE: Observable<'or, T, E> + Clone,
S: Observer<T, E> + Clone + MaybeSend + 'or,
{
let sub = self.source.clone().subscribe(self.subject.clone());
ConnectableController {
source: self.source,
subject: self.subject,
state: Connected(sub),
}
}
pub fn ref_count<'or, T, E>(self) -> RefCount<'or, T, E, OE, S>
where
OE: Observable<'or, T, E>,
S: Clone,
{
RefCount::new(self)
}
}
impl<OE, S, D> ConnectableController<OE, S, Connected<D>>
where
D: Disposable,
{
pub fn disconnect(self) -> ConnectableController<OE, S, Disconnected> {
let Self {
source,
subject,
state,
} = self;
drop(state);
ConnectableController {
source,
subject,
state: Disconnected,
}
}
}
impl<OE, S, State> ConnectableController<OE, S, State> {
pub fn observable(&self) -> SubjectObservable<S>
where
S: Clone,
{
SubjectObservable::new(self.subject.clone())
}
}