diff --git a/src/contexts/component_factory.rs b/src/contexts/component_factory.rs new file mode 100644 index 0000000..bf1a3b9 --- /dev/null +++ b/src/contexts/component_factory.rs @@ -0,0 +1,24 @@ +use super::component::Component; +use super::model_i::{Context, FromContext}; + +use std::any::{Any, type_name}; + +trait ComponentFactory { + type Input; + type Output; + + fn build(&self, input: Self::Input) -> Result; +} + +trait ContextComponentFactory: ComponentFactory { + fn build_from_context(&self, context: &Context) -> Result; +} + +impl , Output=O>> ContextComponentFactory for CF { + fn build_from_context(&self, context: &Context) -> Result { + let input = FromContext::from(context).ok_or_else(|| format!("Could not find retrieve component of type {} from context", type_name::()))?; + self.build(input) + } +} + + diff --git a/src/contexts/mod.rs b/src/contexts/mod.rs index b6acac3..812c77a 100644 --- a/src/contexts/mod.rs +++ b/src/contexts/mod.rs @@ -1,3 +1,4 @@ mod model_i; mod component; mod component_map; +mod component_factory; diff --git a/src/contexts/model_i.rs b/src/contexts/model_i.rs index 7788a97..b1806d0 100644 --- a/src/contexts/model_i.rs +++ b/src/contexts/model_i.rs @@ -4,21 +4,21 @@ use super::component::*; use super::component_map::*; #[allow(dead_code)] -struct Context<'t> { +pub struct Context<'t> { map: ComponentMap, base_context: Option<&'t Context<'t>>, } #[allow(dead_code)] impl<'t> Context<'t> { - fn new() -> Context<'t> { + pub fn new() -> Context<'t> { Context { map: ComponentMap::new(), base_context: None, } } - fn get(&self) -> Option> { + pub fn get(&self) -> Option> { match self.map.get() { component @ Some(_) => component, _ => match self.base_context { @@ -28,22 +28,22 @@ impl<'t> Context<'t> { } } - fn set(&mut self, component: T) { + pub fn set(&mut self, component: T) { self.map.set(component) } - fn subcontext(&self) -> Context { + pub fn subcontext(&self) -> Context { let mut context = Context::new(); context.base_context = Some(self); context } } -trait FromContext: Sized { +pub trait FromContext: Sized { fn from(context: &Context) -> Option; } -impl FromContext for Component { +impl FromContext for Component { fn from(context: &Context) -> Option { context.get() }