config_parser/
config.rs

1use std::{iter, slice};
2
3/// Represents a block in the config file or the document root
4#[derive(Debug, PartialEq, Eq)]
5pub struct ConfigBlock {
6    name: String,
7    params: Vec<String>,
8    inner: Vec<ConfigBlock>
9}
10
11impl ConfigBlock {
12    /// Creates a new ConfigBlock. This probably isn't very useful to you.
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    /// Adds a new sub block. This probably isn't very useful for you
22    pub fn add_block(&mut self, block: ConfigBlock) {
23        self.inner.push(block);
24    }
25
26    /// Returns an iterator of all inner config options with the specified name
27    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    /// Returns the name of the option key
35    pub fn name(&self) -> &str {
36        &self.name
37    }
38
39    /// Returns all inner config options
40    pub fn inner<'a>(&'a self) -> &'a Vec<ConfigBlock> {
41        &self.inner
42    }
43
44    /// Returns the parameter count
45    pub fn len(&self) -> usize {
46        self.params.len()
47    }
48
49    /// Returns a parameter. Panics if the parameter index is too high
50    pub fn get(&self, i: usize) -> &str {
51        &self.params[i]
52    }
53
54    /// Returns a parameter. Returns None if the index is too high
55    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
64pub struct ConfigIter<'a> {
65    it: slice::Iter<'a, ConfigBlock>,
66    name: &'a str
67}
68
69impl <'a> iter::Iterator for ConfigIter <'a> {
70    type Item = &'a ConfigBlock;
71    fn next(&mut self) -> Option<&'a ConfigBlock> {
72        loop {
73            match self.it.next() {
74                Some(c) if c.name() == self.name => return Some(c),
75                Some(_) => {},
76                None => return None
77            }
78        }
79    }
80
81    fn size_hint(&self) -> (usize, Option<usize>) {
82        (0, self.it.size_hint().1)
83    }
84}