nginx_config_mod/
config.rs

1use std::io::Read;
2use std::fmt;
3use std::path::{PathBuf, Path};
4use std::fs::File;
5
6use errors::{ReadError, ReadEnum};
7use nginx_config;
8use nginx_config::visitors::DirectiveIter;
9use nginx_config::ast::{Directive, Main};
10
11
12pub struct Config {
13    #[allow(dead_code)]
14    filename: Option<PathBuf>,
15    ast: Ast,
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19pub enum EntryPoint {
20    Main,
21    Http,
22    Server,
23    Location,
24}
25
26enum Ast {
27    Main(Main),
28    Http(Vec<Directive>),
29    Server(Vec<Directive>),
30    Location(Vec<Directive>),
31}
32
33impl Config {
34    pub fn partial_file(entry_point: EntryPoint, path: &Path)
35        -> Result<Config, ReadError>
36    {
37        Ok(Config::_partial_file(entry_point, path)?)
38    }
39
40    fn _partial_file(entry_point: EntryPoint, path: &Path)
41        -> Result<Config, ReadEnum>
42    {
43        use self::EntryPoint as E;
44        use self::Ast as A;
45
46        let mut buf = String::with_capacity(1024);
47        let mut f = File::open(path).map_err(ReadEnum::Input)?;
48        f.read_to_string(&mut buf).map_err(ReadEnum::Input)?;
49
50        let ast = match entry_point {
51            E::Main => A::Main(nginx_config::parse_main(&buf)?),
52            E::Http => A::Http(nginx_config::parse_directives(&buf)?),
53            E::Server => A::Server(nginx_config::parse_directives(&buf)?),
54            E::Location => A::Location(nginx_config::parse_directives(&buf)?),
55        };
56        Ok(Config {
57            filename: Some(path.to_path_buf()),
58            ast,
59        })
60    }
61
62    pub fn directives(&self) -> &[Directive] {
63        use self::Ast::*;
64        match self.ast {
65            Main(ref ast) => &ast.directives,
66            Http(ref dirs) | Server(ref dirs) | Location(ref dirs) => dirs,
67        }
68    }
69    pub fn all_directives(&self) -> DirectiveIter {
70        use self::Ast::*;
71        match self.ast {
72            Main(ref ast) => ast.all_directives(),
73            Http(ref dirs) | Server(ref dirs) | Location(ref dirs) => {
74                DirectiveIter::depth_first(dirs)
75            },
76        }
77    }
78    pub fn directives_mut(&mut self) -> &mut Vec<Directive> {
79        use self::Ast::*;
80        match self.ast {
81            Main(ref mut ast) => &mut ast.directives,
82            Http(ref mut dirs) | Server(ref mut dirs) | Location(ref mut dirs)
83            => dirs,
84        }
85    }
86}
87
88impl fmt::Display for Config {
89    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90        use self::Ast::*;
91        match self.ast {
92            Main(ref ast) => write!(f, "{}", ast),
93            Http(ref dirs) | Server(ref dirs) | Location(ref dirs)
94            => {
95                if dirs.len() > 0 {
96                    write!(f, "{}", &dirs[0])?;
97                    for d in &dirs[1..] {
98                        write!(f, "\n{}", d)?;
99                    }
100                }
101                Ok(())
102            }
103        }
104    }
105}