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

  1. use std::cell::RefCell;
  2. use std::collections::{HashMap, HashSet};
  3. use symbols::Symbol;
  4. use resources::Resource;
  5. pub trait SymbolRepository<'a> {
  6. fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>>;
  7. }
  8. impl<'a, C> SymbolRepository<'a> for C where C: Fn(&Resource) -> Option<Box<Symbol + 'a>> {
  9. fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>> {
  10. self(resource)
  11. }
  12. }
  13. pub struct DispatchingSymbolRepository<'a> {
  14. repositories: HashMap<&'static str, Box<SymbolRepository<'a>>>
  15. }
  16. impl<'a> DispatchingSymbolRepository<'a> {
  17. pub fn new(repositories: HashMap<&'static str, Box<SymbolRepository<'a>>>) -> DispatchingSymbolRepository<'a> {
  18. DispatchingSymbolRepository { repositories: repositories }
  19. }
  20. }
  21. impl<'a> SymbolRepository<'a> for DispatchingSymbolRepository<'a> {
  22. fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>> {
  23. self.repositories.get(resource.get_type()).and_then(|repo| repo.get_symbol(resource))
  24. }
  25. }
  26. use std::marker::PhantomData;
  27. pub struct NonRepeatingSymbolRepository<'a, R> where R: SymbolRepository<'a> {
  28. upstream: R,
  29. done: RefCell<HashSet<Resource>>,
  30. d: PhantomData<Box<Symbol + 'a>>
  31. }
  32. impl<'a, R> NonRepeatingSymbolRepository<'a, R> where R: SymbolRepository<'a> {
  33. pub fn new(repository: R) -> Self {
  34. NonRepeatingSymbolRepository { upstream: repository, done: RefCell::new(HashSet::new()), d: PhantomData }
  35. }
  36. }
  37. impl<'a, R> SymbolRepository<'a> for NonRepeatingSymbolRepository<'a, R> where R: SymbolRepository<'a> {
  38. fn get_symbol(&self, resource: &Resource) -> Option<Box<Symbol + 'a>> {
  39. let mut done = self.done.borrow_mut();
  40. if done.contains(&resource) {
  41. None
  42. } else {
  43. done.insert(resource.clone());
  44. self.upstream.get_symbol(resource)
  45. }
  46. }
  47. }