use crate::{ComposableOperator, Signal, Subscriber};

use super::OptionSubscriber;

/// [Operator]s with the same outputs as its inputs can be made optional.
///
/// If upon subscription, the operator was [Some] the subscription will be
/// created with the operator, if it's [None], values will just pass through.
impl<In, InError, Op> ComposableOperator for Option<Op>
where
	Op: ComposableOperator<In = In, InError = InError, Out = In, OutError = InError>,
	In: Signal,
	InError: Signal,
{
	type Subscriber<Destination>
		= OptionSubscriber<Op::Subscriber<Destination>, Destination>
	where
		Destination: 'static + Subscriber<In = Self::Out, InError = Self::OutError> + Send + Sync,
		Op::Subscriber<Destination>: Subscriber;

	fn operator_subscribe<Destination>(
		&mut self,
		destination: Destination,
	) -> Self::Subscriber<Destination>
	where
		Destination: Subscriber<In = Self::Out, InError = Self::OutError> + Send + Sync,
	{
		match self {
			Some(operator) => OptionSubscriber::Some(operator.operator_subscribe(destination)),
			None => OptionSubscriber::None(destination),
		}
	}
}
