use std::any::Any;
use std::rc::Rc;
use std::cell::RefCell;
use std::ops::DerefMut;
use typedef::TypeDef;
use { MetaFactory, ToMetaFactory };
use { Factory, Getter };
use error::{ FactoryErrorKind };
use aggregate::Aggregate;
#[stable]
impl<T:'static> ToMetaFactory for (||:'static -> T) {
fn to_metafactory<'a>(self) -> Box<MetaFactory + 'a> {
box Rc::new(RefCell::new(self))
}
}
impl<T:'static> MetaFactory for Rc<RefCell<||:'static -> T>> {
fn get_type(&self) -> TypeDef {
TypeDef::of::<T>()
}
fn get_arg_types(&self) -> Vec<TypeDef> {
Vec::new()
}
fn new(&self, _arg_getters: Vec<Box<Any>>) -> Result<Box<Any>, FactoryErrorKind> {
Ok(
box Factory::<T>::new(
box self.clone()
) as Box<Any>
)
}
fn new_aggregate(&self) -> Aggregate<'static> {
Aggregate::new::<T>()
}
}
impl<T: 'static> Getter<T> for Rc<RefCell<||:'static -> T>> {
fn take(&self) -> T {
(*(self.borrow_mut().deref_mut()))()
}
fn boxed_clone(&self) -> Box<Getter<T> + 'static> {
box self.clone()
}
}
#[cfg(test)]
mod test {
use typedef::TypeDef;
use super::super::super::{ ToMetaFactory, MetaFactory, AsFactoryExt };
#[test]
fn should_return_correct_type() {
assert_eq!(
create(|| 24i).get_type(),
TypeDef::of::<int>()
);
assert_eq!(
create(|| 1f32).get_type(),
TypeDef::of::<f32>()
);
assert_eq!(
create(|| "aaa".to_string()).get_type(),
TypeDef::of::<String>()
);
assert_eq!(
create(|| box "aaa".to_string()).get_type(),
TypeDef::of::<Box<String>>()
);
}
#[test]
fn should_require_no_arguments() {
assert_eq!(
create(|| 24i).get_arg_types().len(),
0
);
}
#[test]
fn should_build_usable_factory() {
assert_eq!(
create(|| 24i).new(Vec::new()).ok().unwrap().as_factory_of::<int>().unwrap().take(),
24i
);
}
#[test]
fn factory_clone_should_return_same_value() {
let factory = create(|| 24i).new(Vec::new()).ok().unwrap().as_factory_of::<int>().unwrap();
assert_eq!(
factory.take(),
factory.clone().take()
);
}
fn create<'r, T: ToMetaFactory>(source: T) -> Box<MetaFactory + 'r> {
source.to_metafactory()
}
}