#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
use std::marker;
use std::mem;
#[derive(Copy, Clone)]
pub struct DynFolder<Output, Item, Func> {
output: Output,
function: Func,
item: marker::PhantomData<Item>,
}
impl<Output, Item, Func> DynFolder<Output, Item, Func> {
pub fn new(initial: Output, func: Func) -> Self
where
Func: Fn(Output, Item) -> Output,
{
Self {
output: initial,
function: func,
item: marker::PhantomData,
}
}
pub fn into_inner(self) -> Output {
self.output
}
pub fn fold(&mut self, item: Item)
where
Func: Fn(Output, Item) -> Output,
{
#[allow(clippy::uninit_assumed_init)]
let uninit = unsafe { mem::MaybeUninit::<Output>::uninit().assume_init() };
let current_output = mem::replace(&mut self.output, uninit);
let new_output = (self.function)(current_output, item);
let uninit = mem::replace(&mut self.output, new_output);
mem::forget(uninit);
}
}
impl<Output, Item, Func> std::fmt::Debug for DynFolder<Output, Item, Func>
where
Output: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"DynFolder::<{}, {}, _> {{ output: {:?}, function: {} }}",
&std::any::type_name::<Output>(),
&std::any::type_name::<Item>(),
self.output,
&std::any::type_name::<Func>(),
)
}
}
impl<Output, Item, Func> AsRef<Output> for DynFolder<Output, Item, Func> {
fn as_ref(&self) -> &Output {
&self.output
}
}
impl<Output, Item, Func> Extend<Item> for DynFolder<Output, Item, Func>
where
Func: Fn(Output, Item) -> Output,
{
fn extend<It: IntoIterator<Item = Item>>(&mut self, iter: It) {
iter.into_iter().for_each(|i| self.fold(i));
}
}