use crate::Generator;
pub use boulder_derive::repeat as Repeat;
pub use boulder_derive::string_pattern as Pattern;
use num::One;
#[derive(Clone)]
pub struct Const<T>(pub T);
impl<T> Const<T> {
pub fn new(value: T) -> Self {
Self(value)
}
}
impl<T: Clone + 'static> Generator for Const<T> {
type Output = T;
fn generate(&mut self) -> Self::Output {
self.0.clone()
}
}
#[derive(Clone)]
pub struct Inc<T>(pub T);
impl<T> Generator for Inc<T>
where
T: core::ops::AddAssign<T> + One + Clone + 'static,
{
type Output = T;
fn generate(&mut self) -> T {
let res = self.0.clone();
self.0 += T::one();
res
}
}
pub struct Cycle<T>(pub(crate) ::std::iter::Cycle<T>);
impl<T: Iterator + Clone> Cycle<T> {
pub fn new(iter: T) -> Self {
Self(iter.cycle())
}
}
impl<S, T> Generator for Cycle<S>
where
S: Iterator<Item = T> + Clone + 'static,
{
type Output = T;
fn generate(&mut self) -> T {
self.0.next().unwrap()
}
}
pub struct Some<T>(pub T);
impl<T: Generator> Generator for Some<T> {
type Output = Option<<T as Generator>::Output>;
fn generate(&mut self) -> Self::Output {
::std::option::Option::Some(self.0.generate())
}
}
impl<F, T> Generator for F
where
F: FnMut() -> T + 'static,
{
type Output = T;
fn generate(&mut self) -> Self::Output {
self()
}
}
pub struct Sample<T, U, V> {
pub(crate) value: T,
pub(crate) count: U,
pub(crate) _result_marker: core::marker::PhantomData<V>,
}
impl<T, U, V> Sample<T, U, V>
where
T: Generator,
U: Generator<Output = usize>,
V: FromIterator<<T as Generator>::Output> + 'static,
{
pub fn new(value: T, count: U) -> Self {
Self {
value,
count,
_result_marker: Default::default(),
}
}
}
impl<T, U, V, X> Generator for Sample<T, U, V>
where
T: Generator<Output = X>,
U: Generator<Output = usize>,
V: FromIterator<X> + 'static,
{
type Output = V;
fn generate(&mut self) -> Self::Output {
super::GeneratorMutIterator {
gen: &mut self.value,
}
.take(self.count.generate())
.collect()
}
}
pub struct Time<T: chrono::TimeZone> {
pub(crate) instant: chrono::DateTime<T>,
pub(crate) step: chrono::Duration,
}
impl<T: chrono::TimeZone> Time<T> {
pub fn new(start: chrono::DateTime<T>, step: chrono::Duration) -> Self {
Self {
instant: start,
step,
}
}
}
impl<T: chrono::TimeZone + 'static> Generator for Time<T> {
type Output = chrono::DateTime<T>;
fn generate(&mut self) -> Self::Output {
let res = self.instant.clone();
self.instant = self.instant.clone() + self.step;
res
}
}
#[derive(Clone)]
pub struct Subsets<T: Clone> {
pub(crate) base: Vec<T>,
pub(crate) index: usize,
}
impl<T: Clone> Subsets<T> {
pub fn new<X: IntoIterator<Item = T>>(base: X) -> Self {
Self {
base: base.into_iter().collect(),
index: 0,
}
}
}
impl<T: Clone + 'static> Generator for Subsets<T> {
type Output = Vec<T>;
fn generate(&mut self) -> Self::Output {
let mut v = Vec::new();
for i in 0..std::cmp::min(std::mem::size_of::<usize>() * 8, self.base.len()) {
if self.index & (1usize << i) != 0 {
v.push(self.base[i].clone());
}
}
self.index += 1;
v
}
}
#[derive(Clone)]
pub struct Repeat<T: Clone> {
pub(crate) base: Vec<T>,
pub(crate) index: usize,
}
impl<T: Clone> Repeat<T> {
pub fn new<X: IntoIterator<Item = T>>(base: X) -> Self {
Self {
base: base.into_iter().collect(),
index: 0,
}
}
}
impl<T: Clone + 'static> Generator for Repeat<T> {
type Output = T;
fn generate(&mut self) -> Self::Output {
let res = self.base[self.index % self.base.len()].clone();
self.index = (self.index + 1usize) % self.base.len();
res
}
}