use std::{fmt::Debug, ops::ControlFlow};
use crate::collector::{Collector, CollectorBase, assert_collector_base};
#[derive(Debug, Clone, Default)]
pub struct Count {
count: usize,
}
impl Count {
#[inline]
pub const fn new() -> Self {
assert_collector_base(Count { count: 0 })
}
#[inline]
pub const fn get(&self) -> usize {
self.count
}
#[inline]
fn increment(&mut self) {
self.count += 1;
}
}
impl CollectorBase for Count {
type Output = usize;
#[inline]
fn finish(self) -> usize {
self.count
}
}
impl<T> Collector<T> for Count {
#[inline]
fn collect(&mut self, _: T) -> ControlFlow<()> {
self.increment();
ControlFlow::Continue(())
}
#[inline]
fn collect_many(&mut self, items: impl IntoIterator<Item = T>) -> ControlFlow<()> {
self.count += items.into_iter().count();
ControlFlow::Continue(())
}
#[inline]
fn collect_then_finish(self, items: impl IntoIterator<Item = T>) -> Self::Output {
self.count + items.into_iter().count()
}
}
#[cfg(all(test, feature = "std"))]
mod proptests {
use proptest::prelude::*;
use proptest::test_runner::TestCaseResult;
use crate::test_utils::{BasicCollectorTester, CollectorTesterExt, PredError};
use super::*;
proptest! {
#[test]
fn all_collect_methods(
count in ..=9_usize,
) {
all_collect_methods_impl(count)?;
}
}
fn all_collect_methods_impl(count: usize) -> TestCaseResult {
BasicCollectorTester {
iter_factory: || std::iter::repeat_n((), count),
collector_factory: Count::new,
should_break_pred: |_| false,
pred: |iter, output, remaining| {
if iter.count() != output {
Err(PredError::IncorrectOutput)
} else if remaining.next().is_some() {
Err(PredError::IncorrectIterConsumption)
} else {
Ok(())
}
},
}
.test_collector()
}
}