summaryrefslogtreecommitdiffstats
path: root/lib/src/path/mod.rs
blob: 46e22907d88ca2196a52b324f0bcaac0f9a52746 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use std::str::FromStr;
use nom::ErrorKind;
use error::*;
use value::{Value, ValueKind};

mod parser;

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum Expression {
    Identifier(String),
    Child(Box<Expression>, String),
    Subscript(Box<Expression>, i32),
}

impl FromStr for Expression {
    type Err = ConfigError;

    fn from_str(s: &str) -> Result<Expression> {
        parser::from_str(s.as_bytes()).to_result().map_err(|kind| {
            ConfigError::PathParse(kind)
        })
    }
}

impl Expression {
    pub fn get<'a>(self, root: &'a Value) -> Option<&'a Value> {
        match self {
            Expression::Identifier(id) => {
                match root.kind {
                    // `x` access on a table is equivalent to: map[x]
                    ValueKind::Table(ref map) => map.get(&id),

                    // all other variants return None
                    _ => None,
                }
            }

            _ => {
                unimplemented!();
            }
        }
    }
}