traits for ComponentFactory and ContextComponentFactory

feature/battle
brnrs 5 years ago
parent 28564b11bd
commit 1a52695945
  1. 24
      src/contexts/component_factory.rs
  2. 1
      src/contexts/mod.rs
  3. 14
      src/contexts/model_i.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<Self::Output, String>;
}
trait ContextComponentFactory: ComponentFactory {
fn build_from_context(&self, context: &Context) -> Result<Self::Output, String>;
}
impl <T:Any + Sized + 'static, O, CF: ComponentFactory<Input=Component<T>, Output=O>> ContextComponentFactory for CF {
fn build_from_context(&self, context: &Context) -> Result<Self::Output, String> {
let input = FromContext::from(context).ok_or_else(|| format!("Could not find retrieve component of type {} from context", type_name::<T>()))?;
self.build(input)
}
}

@ -1,3 +1,4 @@
mod model_i; mod model_i;
mod component; mod component;
mod component_map; mod component_map;
mod component_factory;

@ -4,21 +4,21 @@ use super::component::*;
use super::component_map::*; use super::component_map::*;
#[allow(dead_code)] #[allow(dead_code)]
struct Context<'t> { pub struct Context<'t> {
map: ComponentMap, map: ComponentMap,
base_context: Option<&'t Context<'t>>, base_context: Option<&'t Context<'t>>,
} }
#[allow(dead_code)] #[allow(dead_code)]
impl<'t> Context<'t> { impl<'t> Context<'t> {
fn new() -> Context<'t> { pub fn new() -> Context<'t> {
Context { Context {
map: ComponentMap::new(), map: ComponentMap::new(),
base_context: None, base_context: None,
} }
} }
fn get<T: Any + Sized + 'static>(&self) -> Option<Component<T>> { pub fn get<T: Any + Sized + 'static>(&self) -> Option<Component<T>> {
match self.map.get() { match self.map.get() {
component @ Some(_) => component, component @ Some(_) => component,
_ => match self.base_context { _ => match self.base_context {
@ -28,22 +28,22 @@ impl<'t> Context<'t> {
} }
} }
fn set<T: Any + Sized + 'static>(&mut self, component: T) { pub fn set<T: Any + Sized + 'static>(&mut self, component: T) {
self.map.set(component) self.map.set(component)
} }
fn subcontext(&self) -> Context { pub fn subcontext(&self) -> Context {
let mut context = Context::new(); let mut context = Context::new();
context.base_context = Some(self); context.base_context = Some(self);
context context
} }
} }
trait FromContext: Sized { pub trait FromContext: Sized {
fn from(context: &Context) -> Option<Self>; fn from(context: &Context) -> Option<Self>;
} }
impl <T> FromContext for Component<T> { impl <T: Any + Sized + 'static> FromContext for Component<T> {
fn from(context: &Context) -> Option<Self> { fn from(context: &Context) -> Option<Self> {
context.get() context.get()
} }

Loading…
Cancel
Save