use std::fmt::{Display, Write};
pub mod error;
pub use self::error::{
Result,
Error
};
enum State {
Normal,
LeftBrace,
RightBrace,
}
use self::State::*;
pub fn format(fmt: &str, args: &[&Display]) -> Result<String> {
let mut buffer = String::with_capacity(fmt.len());
try!(write_format(&mut buffer, fmt, args));
Ok(buffer)
}
pub fn write_format<W: Write>(buffer: &mut W, fmt: &str, args: &[&Display]) -> Result<()> {
let mut args = args.iter();
let mut state = Normal;
for ch in fmt.chars() {
match state {
Normal => match ch {
'{' => state = LeftBrace,
'}' => state = RightBrace,
_ => try!(buffer.write_char(ch))
},
LeftBrace => match ch {
'{' => {
try!(buffer.write_char(ch));
state = Normal
},
'}' => {
match args.next() {
Some(arg) => try!(write!(buffer, "{}", arg)),
None => return Err(Error::NotEnoughArgs)
};
state = Normal
},
_ => return Err(Error::UnexpectedChar) },
RightBrace => match ch {
'}' => {
try!(buffer.write_char(ch));
state = Normal
},
_ => return return Err(Error::UnexpectedRightBrace) }
}
}
Ok(())
}