corosync_config_parser/
config.rs1use std::iter;
2use std::slice;
3
4#[derive(Debug, PartialEq, Eq)]
6pub struct ConfigBlock {
7 name: String,
8 params: Vec<String>,
9 inner: Vec<ConfigBlock>,
10}
11
12impl ConfigBlock {
13 pub fn new(name: String, params: Vec<String>, inner: Vec<ConfigBlock>) -> ConfigBlock {
14 ConfigBlock {
15 name: name,
16 params: params,
17 inner: inner,
18 }
19 }
20
21 pub fn add_block(&mut self, block: ConfigBlock) {
23 self.inner.push(block);
24 }
25
26 pub fn matching<'a>(&'a self, name: &'a str) -> ConfigIter<'a> {
28 ConfigIter {
29 it: self.inner.iter(),
30 name: name,
31 }
32 }
33
34 pub fn name(&self) -> &str {
36 &self.name
37 }
38
39 pub fn inner<'a>(&'a self) -> &'a Vec<ConfigBlock> {
41 &self.inner
42 }
43
44 pub fn len(&self) -> usize {
46 self.params.len()
47 }
48
49 pub fn get(&self, i: usize) -> &str {
51 &self.params[i]
52 }
53
54 pub fn get_opt(&self, i: usize) -> Option<&str> {
56 if i < self.params.len() {
57 Some(&self.params[i])
58 } else {
59 None
60 }
61 }
62
63 pub fn path<'a>(&'a self, keys: Vec<&'a str>) -> Option<&str> {
64 let last_config_block =
65 keys.iter()
66 .fold(Some(self), |accumulator, key| match accumulator {
67 Some(config_block) => config_block.matching(key).nth(0),
68 None => None,
69 });
70
71 match last_config_block {
72 Some(config_block) => Some(config_block.get(0)),
73 None => None,
74 }
75 }
76}
77
78pub struct ConfigIter<'a> {
79 it: slice::Iter<'a, ConfigBlock>,
80 name: &'a str,
81}
82
83impl<'a> iter::Iterator for ConfigIter<'a> {
84 type Item = &'a ConfigBlock;
85 fn next(&mut self) -> Option<&'a ConfigBlock> {
86 loop {
87 match self.it.next() {
88 Some(c) if c.name() == self.name => return Some(c),
89 Some(_) => {}
90 None => return None,
91 }
92 }
93 }
94
95 fn size_hint(&self) -> (usize, Option<usize>) {
96 (0, self.it.size_hint().1)
97 }
98}