use crate::streams::*;
pub struct IfStream<GC, GI> {
condition: GC,
input: GI,
}
impl<GC, GI> IfStream<GC, GI> {
pub const fn new(condition: GC, input: GI) -> Self {
Self { condition, input }
}
}
impl<T, GC, GI, E> Getter<T, E> for IfStream<GC, GI>
where
GC: Getter<bool, E>,
GI: Getter<T, E>,
E: Clone + Debug,
{
fn get(&self) -> Output<T, E> {
let condition = match self.condition.get()? {
Some(output) => output.value,
None => false,
};
if condition {
self.input.get()
} else {
Ok(None)
}
}
}
impl<GC, GI, E> Updatable<E> for IfStream<GC, GI>
where
GC: Updatable<E>,
GI: Updatable<E>,
E: Clone + Debug,
{
fn update(&mut self) -> NothingOrError<E> {
self.input.update()?;
self.condition.update()?;
Ok(())
}
}
pub struct IfElseStream<GC, GT, GF> {
condition: GC,
true_output: GT,
false_output: GF,
}
impl<GC, GT, GF> IfElseStream<GC, GT, GF> {
pub const fn new(condition: GC, true_output: GT, false_output: GF) -> Self {
Self {
condition,
true_output,
false_output,
}
}
}
impl<T, GC, GT, GF, E> Getter<T, E> for IfElseStream<GC, GT, GF>
where
GC: Getter<bool, E>,
GT: Getter<T, E>,
GF: Getter<T, E>,
E: Clone + Debug,
{
fn get(&self) -> Output<T, E> {
let condition = match self.condition.get()? {
Some(output) => output.value,
None => return Ok(None),
};
if condition {
self.true_output.get()
} else {
self.false_output.get()
}
}
}
impl<GC, GT, GF, E> Updatable<E> for IfElseStream<GC, GT, GF>
where
GC: Updatable<E>,
GT: Updatable<E>,
GF: Updatable<E>,
E: Clone + Debug,
{
fn update(&mut self) -> NothingOrError<E> {
self.true_output.update()?;
self.false_output.update()?;
self.condition.update()?;
Ok(())
}
}
pub struct FreezeStream<T, GC, GI, E> {
condition: GC,
input: GI,
freeze_value: Output<T, E>,
}
impl<T, GC, GI, E> FreezeStream<T, GC, GI, E> {
pub const fn new(condition: GC, input: GI) -> Self {
Self {
condition,
input,
freeze_value: Ok(None),
}
}
}
impl<T, GC, GI, E> Getter<T, E> for FreezeStream<T, GC, GI, E>
where
Self: Updatable<E>,
Output<T, E>: Clone,
E: Clone + Debug,
{
fn get(&self) -> Output<T, E> {
self.freeze_value.clone()
}
}
impl<T, GC, GI, E> Updatable<E> for FreezeStream<T, GC, GI, E>
where
Output<T, E>: Clone,
GC: Getter<bool, E>,
GI: Getter<T, E>,
E: Clone + Debug,
{
fn update(&mut self) -> NothingOrError<E> {
self.input.update()?;
self.condition.update()?;
let condition = match self.condition.get() {
Err(error) => {
self.freeze_value = Err(error.clone());
return Err(error);
}
Ok(None) => {
self.freeze_value = Ok(None);
return Ok(());
}
Ok(Some(condition)) => condition.value,
};
if !condition {
let gotten = self.input.get();
self.freeze_value = gotten.clone();
match gotten {
Ok(_) => {}
Err(error) => return Err(error),
}
}
Ok(())
}
}