use crate::streams::*;
enum AndState {
DefinitelyFalse, MaybeTrue, ReturnableTrue, }
impl AndState {
#[inline]
fn none(&mut self) {
match self {
AndState::ReturnableTrue => *self = AndState::MaybeTrue,
_ => (),
}
}
}
pub struct AndStream<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug> {
input1: Reference<G1>,
input2: Reference<G2>,
phantom_e: PhantomData<E>,
}
impl<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug>
AndStream<G1, G2, E>
{
pub const fn new(input1: Reference<G1>, input2: Reference<G2>) -> Self {
Self {
input1: input1,
input2: input2,
phantom_e: PhantomData,
}
}
}
impl<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug> Getter<bool, E>
for AndStream<G1, G2, E>
{
fn get(&self) -> Output<bool, E> {
let gotten1 = self.input1.borrow().get()?;
let gotten2 = self.input2.borrow().get()?;
let mut time = None;
let mut and_state = AndState::ReturnableTrue;
match gotten1 {
Some(datum) => {
time = Some(datum.time);
if !datum.value {
and_state = AndState::DefinitelyFalse;
}
}
None => {
and_state.none();
}
}
match gotten2 {
Some(datum) => {
match time {
Some(existing) => {
if datum.time > existing {
time = Some(datum.time);
}
}
None => time = Some(datum.time),
}
if !datum.value {
and_state = AndState::DefinitelyFalse;
}
}
None => {
and_state.none();
}
}
let time = match time {
Some(time) => time,
None => return Ok(None),
};
match and_state {
AndState::DefinitelyFalse => Ok(Some(Datum::new(time, false))),
AndState::MaybeTrue => Ok(None),
AndState::ReturnableTrue => Ok(Some(Datum::new(time, true))),
}
}
}
impl<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug> Updatable<E>
for AndStream<G1, G2, E>
{
fn update(&mut self) -> NothingOrError<E> {
Ok(())
}
}
enum OrState {
DefinitelyTrue, MaybeFalse, ReturnableFalse, }
impl OrState {
#[inline]
fn none(&mut self) {
match self {
OrState::ReturnableFalse => *self = OrState::MaybeFalse,
_ => (),
}
}
}
pub struct OrStream<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug> {
input1: Reference<G1>,
input2: Reference<G2>,
phantom_e: PhantomData<E>,
}
impl<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug>
OrStream<G1, G2, E>
{
pub const fn new(input1: Reference<G1>, input2: Reference<G2>) -> Self {
Self {
input1: input1,
input2: input2,
phantom_e: PhantomData,
}
}
}
impl<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug> Getter<bool, E>
for OrStream<G1, G2, E>
{
fn get(&self) -> Output<bool, E> {
let gotten1 = self.input1.borrow().get()?;
let gotten2 = self.input2.borrow().get()?;
let mut time = None;
let mut or_state = OrState::ReturnableFalse;
match gotten1 {
Some(datum) => {
time = Some(datum.time);
if datum.value {
or_state = OrState::DefinitelyTrue;
}
}
None => {
or_state.none();
}
}
match gotten2 {
Some(datum) => {
match time {
Some(existing) => {
if datum.time > existing {
time = Some(datum.time);
}
}
None => time = Some(datum.time),
}
if datum.value {
or_state = OrState::DefinitelyTrue;
}
}
None => {
or_state.none();
}
}
let time = match time {
Some(time) => time,
None => return Ok(None),
};
match or_state {
OrState::DefinitelyTrue => Ok(Some(Datum::new(time, true))),
OrState::MaybeFalse => Ok(None),
OrState::ReturnableFalse => Ok(Some(Datum::new(time, false))),
}
}
}
impl<G1: Getter<bool, E> + ?Sized, G2: Getter<bool, E> + ?Sized, E: Copy + Debug> Updatable<E>
for OrStream<G1, G2, E>
{
fn update(&mut self) -> NothingOrError<E> {
Ok(())
}
}
pub struct NotStream<G: Getter<bool, E> + ?Sized, E: Copy + Debug> {
input: Reference<G>,
phantom_e: PhantomData<E>,
}
impl<G: Getter<bool, E> + ?Sized, E: Copy + Debug> NotStream<G, E> {
pub const fn new(input: Reference<G>) -> Self {
Self {
input: input,
phantom_e: PhantomData,
}
}
}
impl<G: Getter<bool, E> + ?Sized, E: Copy + Debug> Getter<bool, E> for NotStream<G, E> {
fn get(&self) -> Output<bool, E> {
match self.input.borrow().get() {
Ok(Some(datum)) => Ok(Some(!datum)),
Ok(None) => Ok(None),
Err(error) => Err(error),
}
}
}
impl<G: Getter<bool, E> + ?Sized, E: Copy + Debug> Updatable<E> for NotStream<G, E> {
fn update(&mut self) -> NothingOrError<E> {
Ok(())
}
}