A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
1.8 KiB

use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use symbols::Symbol;
use resources::Resource;
pub trait SymbolRepository<'a> {
fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>>;
}
impl<'a, C> SymbolRepository<'a> for C where C: Fn(&Resource) -> Option<Box<Symbol + 'a>> {
fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>> {
self(resource)
}
}
pub struct DispatchingSymbolRepository<'a> {
repositories: HashMap<&'static str, Box<SymbolRepository<'a>>>
}
impl<'a> DispatchingSymbolRepository<'a> {
pub fn new(repositories: HashMap<&'static str, Box<SymbolRepository<'a>>>) -> DispatchingSymbolRepository<'a> {
DispatchingSymbolRepository { repositories: repositories }
}
}
impl<'a> SymbolRepository<'a> for DispatchingSymbolRepository<'a> {
fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>> {
self.repositories.get(resource.get_type()).and_then(|repo| repo.get_symbol(resource))
}
}
use std::marker::PhantomData;
pub struct NonRepeatingSymbolRepository<'a, R> where R: SymbolRepository<'a> {
upstream: R,
done: RefCell<HashSet<Resource>>,
d: PhantomData<Box<Symbol + 'a>>
}
impl<'a, R> NonRepeatingSymbolRepository<'a, R> where R: SymbolRepository<'a> {
pub fn new(repository: R) -> Self {
NonRepeatingSymbolRepository { upstream: repository, done: RefCell::new(HashSet::new()), d: PhantomData }
}
}
impl<'a, R> SymbolRepository<'a> for NonRepeatingSymbolRepository<'a, R> where R: SymbolRepository<'a> {
fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>> {
let mut done = self.done.borrow_mut();
if done.contains(&resource) {
None
} else {
done.insert(resource.clone());
self.upstream.get_symbol(resource)
}
}
}