Mercurial > lbo > hg > syslog
changeset 21:eae478565a9f draft
Add method for directly parsing a configuration file
and a manual test (i.e., read/parse/write a configuration)
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sat, 03 Dec 2016 16:09:31 +0100 |
parents | 4914bd1e162f |
children | 226f1c607612 |
files | prototype.toml src/config.rs |
diffstat | 2 files changed, 46 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/prototype.toml Sat Dec 03 15:45:27 2016 +0100 +++ b/prototype.toml Sat Dec 03 16:09:31 2016 +0100 @@ -12,6 +12,10 @@ addr = "10.0.0.2" port = 538 +[remotes.example] +addr = "example.com" +port = 11023 + [files] [files.messages] # All possible options are described here
--- a/src/config.rs Sat Dec 03 15:45:27 2016 +0100 +++ b/src/config.rs Sat Dec 03 16:09:31 2016 +0100 @@ -4,7 +4,10 @@ use std::collections::HashMap; use std::collections::btree_map::Entry; use std::default::Default; +use std::fs; +use std::io::{self, Read}; use std::net::SocketAddr; +use std::path::Path; use std::str::FromStr; use dns_lookup; @@ -15,6 +18,10 @@ /// Parses strings like 0/1s/2m/3h/4d/5w and returns seconds. If no unit is there, seconds is /// assumed. fn parse_duration(s: &str) -> Option<u64> { + if s.len() == 0 { + return None; + } + let s = s.trim(); let suffix = &s[s.len() - 1..]; let num_part = &s[0..s.len() - 1]; @@ -133,7 +140,7 @@ // config structs -#[derive(Clone,Default)] +#[derive(Clone, Debug, Default)] pub struct General { pub bind_path: String, pub max_msg_len: usize, @@ -152,7 +159,7 @@ Ok(g) } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Remote { addr: SocketAddr, } @@ -174,7 +181,7 @@ Err(toml::Error::Custom(format!("Couldn't parse/resolve host {} for {}", addr, name))) } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum CompressType { NoCompression, // TODO: implement flate2 for compression. @@ -200,7 +207,7 @@ } } -#[derive(Clone,Default)] +#[derive(Clone, Debug, Default)] pub struct File { name: String, location: String, @@ -368,7 +375,7 @@ } } -#[derive(Clone,Default)] +#[derive(Clone, Debug, Default)] pub struct Rule { pattern: Matcher, // refers to the file entry name, not the file name. @@ -395,7 +402,7 @@ }) } -#[derive(Clone,Default)] +#[derive(Clone, Debug, Default)] pub struct Config { pub general: General, remotes: HashMap<String, Remote>, @@ -453,9 +460,30 @@ } } - unimplemented!() + Ok(cfg) } else { - return Err(toml::Error::Custom("Couldn't parse configuration".to_string())); + Err(toml::Error::Custom("Couldn't parse configuration".to_string())) + } +} + +pub fn open_and_read_config<P>(p: P) -> io::Result<Config> + where P: AsRef<Path> +{ + let f = try!(fs::OpenOptions::new().read(true).open(p)); + let contents: Vec<u8> = f.bytes().map(|b| b.unwrap_or(' ' as u8)).collect(); + + match String::from_utf8(contents) { + Ok(s) => { + let cfg = decode_config(&s); + + match cfg { + Ok(cfg) => Ok(cfg), + Err(e) => { + Err(io::Error::new(io::ErrorKind::InvalidData, format!("bad config: {}", e))) + } + } + } + Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidInput, "UTF8 decoding failed")), } } @@ -499,4 +527,10 @@ assert_eq!(parse_duration(test), Some(result)); } } + + #[test] + fn test_config_parse_prototype() { + let config = open_and_read_config("./prototype.toml"); + println!("{:?}", config); + } }