diff options
Diffstat (limited to '')
-rw-r--r-- | src/configuration/uapi/mod.rs | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/src/configuration/uapi/mod.rs b/src/configuration/uapi/mod.rs index cba156d..117d970 100644 --- a/src/configuration/uapi/mod.rs +++ b/src/configuration/uapi/mod.rs @@ -5,45 +5,73 @@ use std::io::{Read, Write}; use super::{ConfigError, Configuration}; -const MAX_LINE_LENGTH: usize = 128; +use get::serialize; +use set::LineParser; -struct Parser<C: Configuration, R: Read, W: Write> { - config: C, - reader: R, - writer: W, -} - -impl<C: Configuration, R: Read, W: Write> Parser<C, R, W> { - fn new(&self, reader: R, writer: W, config: C) -> Parser<C, R, W> { - Parser { - config, - reader, - writer, - } - } +const MAX_LINE_LENGTH: usize = 256; - fn parse(&mut self) -> Option<()> { +pub fn process<R: Read, W: Write, C: Configuration>(reader: &mut R, writer: &mut W, config: &C) { + fn operation<R: Read, W: Write, C: Configuration>( + reader: &mut R, + writer: &mut W, + config: &C, + ) -> Result<(), ConfigError> { // read string up to maximum length (why is this not in std?) - let mut line = || { + fn readline<R: Read>(reader: &mut R) -> Result<String, ConfigError> { let mut m: [u8; 1] = [0u8]; let mut l: String = String::with_capacity(MAX_LINE_LENGTH); - while let Ok(_) = self.reader.read_exact(&mut m) { + while let Ok(_) = reader.read_exact(&mut m) { let c = m[0] as char; if c == '\n' { - return Some(l); + return Ok(l); }; l.push(c); if l.len() > MAX_LINE_LENGTH { - break; + return Err(ConfigError::LineTooLong); } } - None + return Err(ConfigError::IOError); + } + + // split into (key, value) pair + fn keypair<'a>(ln: &'a str) -> Result<(&'a str, &'a str), ConfigError> { + let mut split = ln.splitn(2, "="); + match (split.next(), split.next()) { + (Some(key), Some(value)) => Ok((key, value)), + _ => Err(ConfigError::LineTooLong), + } }; - match line()?.as_str() { - "get=1" => Some(()), - "set=1" => Some(()), - _ => None, + // read operation line + match readline(reader)?.as_str() { + "get=1" => serialize(writer, config).map_err(|_| ConfigError::IOError), + "set=1" => { + let mut parser = LineParser::new(config); + loop { + let ln = readline(reader)?; + if ln == "" { + break Ok(()); + }; + let (k, v) = keypair(ln.as_str())?; + parser.parse_line(k, v)?; + } + } + _ => Err(ConfigError::InvalidOperation), } } + + // process operation + let res = operation(reader, writer, config); + log::debug!("{:?}", res); + + // return errno + let _ = writer.write("errno=".as_ref()); + let _ = writer.write( + match res { + Err(e) => e.errno().to_string(), + Ok(()) => "0".to_owned(), + } + .as_ref(), + ); + let _ = writer.write("\n\n".as_ref()); } |