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
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)
|
|
}
|
|
}
|
|
}
|