impl crate::Exhaust for bool {
type Iter = ExhaustBool;
fn exhaust_factories() -> Self::Iter {
ExhaustBool(State::FalseTrue)
}
crate::patterns::factory_is_self!();
}
#[derive(Clone, Debug)]
pub struct ExhaustBool(State);
#[derive(Clone, Debug, Eq, PartialEq)]
enum State {
FalseTrue,
False,
True,
Exhausted,
}
impl Iterator for ExhaustBool {
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
use State::{Exhausted, False, FalseTrue, True};
let (item, state) = match self.0 {
FalseTrue => (Some(false), True),
False => (Some(false), Exhausted),
True => (Some(true), Exhausted),
Exhausted => (None, Exhausted),
};
self.0 = state;
item
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
fn fold<B, F>(mut self, init: B, mut f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
let mut state = init;
if matches!(self.0, State::False | State::FalseTrue) {
state = f(state, false);
}
if matches!(self.0, State::True | State::FalseTrue) {
state = f(state, true);
}
self.0 = State::Exhausted;
state
}
}
impl DoubleEndedIterator for ExhaustBool {
fn next_back(&mut self) -> Option<Self::Item> {
use State::{Exhausted, False, FalseTrue, True};
let (item, state) = match self.0 {
FalseTrue => (Some(true), False),
False => (Some(false), Exhausted),
True => (Some(true), Exhausted),
Exhausted => (None, Exhausted),
};
self.0 = state;
item
}
fn rfold<B, F>(mut self, init: B, mut f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
let mut state = init;
if matches!(self.0, State::True | State::FalseTrue) {
state = f(state, true);
}
if matches!(self.0, State::False | State::FalseTrue) {
state = f(state, false);
}
self.0 = State::Exhausted;
state
}
}
impl core::iter::ExactSizeIterator for ExhaustBool {
fn len(&self) -> usize {
match self.0 {
State::FalseTrue => 2,
State::False | State::True => 1,
State::Exhausted => 0,
}
}
}
impl core::iter::FusedIterator for ExhaustBool {}