1use std::collections::VecDeque;
3
4use ast::Directive;
5use value::Value;
6
7
8#[derive(Debug)]
10pub struct DirectiveIter<'a> {
11 cur: Option<&'a Directive>,
12 queue: VecDeque<&'a Directive>,
13}
14
15impl<'a> DirectiveIter<'a> {
16 pub fn depth_first(start: &[Directive]) -> DirectiveIter {
23 DirectiveIter {
24 cur: None,
25 queue: start.iter().rev().collect()
26 }
27 }
28}
29
30impl<'a> Iterator for DirectiveIter<'a> {
31 type Item = &'a Directive;
32 fn next(&mut self) -> Option<&'a Directive> {
33 match self.cur.take() {
34 Some(dir) => {
35 if let Some(ch) = dir.item.children() {
36 self.queue.extend(ch.iter().rev());
37 }
38 }
39 None => {}
40 }
41 match self.queue.pop_back() {
42 Some(x) => {
43 self.cur = Some(x);
44 return Some(x);
45 }
46 None => None,
47 }
48 }
49}
50
51pub fn visit_mutable<F>(dirs: &mut Vec<Directive>, mut f: F)
53 where F: FnMut(&mut Directive)
54{
55 _visit_mutable(dirs, &mut f)
56}
57
58fn _visit_mutable<F>(dirs: &mut Vec<Directive>, f: &mut F)
59 where F: FnMut(&mut Directive)
60{
61 for dir in dirs {
62 f(dir);
63 match dir.item.children_mut() {
64 Some(children) => _visit_mutable(children, f),
65 None => {}
66 }
67 }
68}
69
70pub fn replace_vars<'a, F, S>(dirs: &mut Vec<Directive>, mut f: F)
75 where F: FnMut(&str) -> Option<S>,
76 S: AsRef<str> + Into<String> + 'a,
77{
78 let mut inner_visitor = |val: &mut Value| {
79 let ref mut f = f;
80 val.replace_vars(f);
81 };
82 visit_mutable(dirs, |dir: &mut Directive| {
83 let ref mut inner_visitor = inner_visitor;
84 dir.visit_values_mut(inner_visitor);
85 });
86}