Crates.io | autofolder |
lib.rs | autofolder |
version | 0.5.1 |
source | src |
created_at | 2022-04-16 20:02:29.631713 |
updated_at | 2024-10-01 20:56:50.19423 |
description | Single-element folding wrapper |
homepage | https://github.com/lpenz/autofolder |
repository | https://github.com/lpenz/autofolder |
max_upload_size | |
id | 569115 |
size | 72,488 |
autofolder provides a single-element "folding" container that can be used to accumulate/select/etc. values in an ad-hoc fashion.
DynFolder
exampleuse autofolder::*;
// Create an autofolder that retains the max u32 value:
let mut max = DynFolder::new(0_u32, std::cmp::max);
// We can "fold-in" individual items:
max.fold(3);
// We can then peek at the running output:
println!("Partial max is {}", max.as_ref());
// And still keep on folding by processing whole iterators:
max.extend((1..=5));
// And finally consume the autofolder to get the final output value:
println!("Max value is {}", max.into_inner());
See also Min
, Max
and MinMax
for useful specific reducers.
Folding in Rust is accomplished via the Iterator::fold
method, like so:
iterator.fold(initial, function);
// (and this is all you can do)
That works well when all the data we need is provided by a single iterator. If we have a
more complex logic, fold
can't be used.
autofolder flips this structure by being built with the initial value and the folding function, and accepting values from various types of different sources during its lifetime.
let mut autofolder = Autofolder::new(initial, function);
// Fold in a whole iterator, can be repeated:
autofolder.extend(iterator);
// Fold in an individual value:
autofolder.fold(value);
This crate provides two types of autofolders with different function binding strategies:
DynFolder
: the folding function is provided as a closure
that is kept in a struct field. Characteristics:
DynFolder
with .collect()
.ImplFolder
due to the use of dynamic dispatch - we are
effectively using a function pointer instead of a function call, after all.ImplFolder
: the folding function is implemented via a trait.
ImplFolder
, defined by the pair of types, can only have one folding
function. Because of that, we can use ImplFolder
with
.collect()
if the output
type implements Default
DynFolder
due to monomorphization, which turns .fold
calls into direct function calls.Reduce in rust is a special kind of folding where the aggregator and the item types of
the folding function are the same (Fn(Item, Item) -> Item
). That allows us to set the
internal autofolder state with the first yielded value, without calling the corresponding
function.
This crate provides the following "autoreducer" types:
DynReduce
: the reduce function is implemented via a trait.
DynFolder
..into_inner()
returns an Option
.reduce
function.ImplReduce
: the reduce function is implemented via a trait.
ImplFolder
..into_inner()
returns an Option
..collect()
even when the type parameters don't
implement Default
.This create also provides some built-in autofolders for specific functions:
Min
: container that keeps only the minimal value iterated, as given by std::cmp::PartialOrd
.Max
: analogous to Max
, but for the max value.MinMax
: container that keeps a tuple with both the min and max values.