Struct metafactory::aggregate::Aggregate
[-]
[+]
[src]
pub struct Aggregate<'a> { // some fields omitted }
Proxy for initializing aggregate factory without caring about the type used.
Its intended use is as a container of factories that produce a
value of the same type. Then it can itself be used to create a new factory
that aggregates values from all its childs and returns all of them
in a Vec<T>
type for single take
.
The most convenient way to initialize a new aggregate is to use
new_aggregate
method on a metafactory. It will make a correctly typed
aggregate based on the metafactory type.
use metafactory::{ metafactory, AsFactoryExt }; fn main() { let true_metafactory = metafactory(|| true); let false_metafactory = metafactory(|| false); // Use any of metafactories to create an aggregate for bool. let mut aggregate = false_metafactory.new_aggregate(); // We can then add both factories to the aggregate. // and make a factory from aggregate. let true_and_false = aggregate .new_factory(vec![ true_metafactory.new(Vec::new()).ok().unwrap(), false_metafactory.new(Vec::new()).ok().unwrap(), ]) .as_factory_of::<Vec<bool>>().unwrap(); assert_eq!(vec![true, false], true_and_false.take()); }
The example bellow show how to initialize and use aggregate without a metafactory.
use std::any::Any; use metafactory::{ metafactory, argless_as_factory, AsFactoryExt }; use metafactory::aggregate::Aggregate; fn main() { // Let's say we know that we will have bunch of `bool` factories. // In that case we create a new aggregate for them: let mut aggregate = Aggregate::new::<bool>(); // Once we actually have our factories, we can inject them into aggregate // without dealing with types. Of course, we should make sure that types // actually match before doing that in the code that is using this // implementation. // Then we can call `new_factory` to convert all dynamic stuff to // statically constructed call hierarchy: let anyed_bool_array_factory = aggregate .new_factory(vec![ argless_as_factory(|| true), argless_as_factory(true), argless_as_factory(|| 4i == 8), ]); // Of course, that returns it anyed (`Box<Any>`), but we can easily get un-anyed version // by downcasting to `Factory<Vec<bool>>` or using a convenience extension // method for that: let bool_array_factory = anyed_bool_array_factory .as_factory_of::<Vec<bool>>().unwrap(); // Calling it should produce expected boolean vector: assert_eq!(bool_array_factory.take(), vec![true, true, false]); // Of course, the aggregate itself should be usable as argument // for other factories: let metafactory_all_true = metafactory(|values: Vec<bool>| { values.iter().fold(true, |a, &i| a & i) }); // We can pass it when constructing a factory for this lambda metafactory: let factory_all_true = metafactory_all_true.new(vec![ box bool_array_factory.clone() as Box<Any> ]) .ok().unwrap() // check for errors here .as_factory_of::<bool>().unwrap() // same story with downcasting ; assert_eq!(factory_all_true.take(), false); // not all values are true }
Methods
impl<'a> Aggregate<'a>
fn new<T: 'static>() -> Aggregate<'a>
Create new aggregate instance for specified type.
fn get_arg_type(&self) -> TypeDef
Return aggregated type.
fn get_container_type(&self) -> TypeDef
Return container type.
fn new_factory(&self, items: Vec<Box<Any>>) -> Box<Any>
Produces factory usable as argument for other factories.
If inner factories make int
values, this method will make factory
that makes Vec<int>
values.