toml-rs/src/show.rs

165 lines
5.6 KiB
Rust
Raw Normal View History

use std::fmt;
2014-12-06 16:51:51 -06:00
use Table as TomlTable;
use Value::{mod, String, Integer, Float, Boolean, Datetime, Array, Table};
struct Printer<'a, 'b:'a> {
output: &'a mut fmt::Formatter<'b>,
stack: Vec<&'a str>,
}
impl fmt::Show for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
String(ref s) => {
try!(write!(f, "\""));
for ch in s.as_slice().chars() {
match ch {
2014-12-12 15:19:22 -06:00
'\u{8}' => try!(write!(f, "\\b")),
'\u{9}' => try!(write!(f, "\\t")),
'\u{a}' => try!(write!(f, "\\n")),
'\u{c}' => try!(write!(f, "\\f")),
'\u{d}' => try!(write!(f, "\\r")),
'\u{22}' => try!(write!(f, "\\\"")),
'\u{5c}' => try!(write!(f, "\\\\")),
ch => try!(write!(f, "{}", ch)),
}
}
write!(f, "\"")
}
Integer(i) => write!(f, "{}", i),
Float(fp) => {
try!(write!(f, "{}", fp));
if fp % 1.0 == 0.0 { try!(write!(f, ".0")) }
Ok(())
}
Boolean(b) => write!(f, "{}", b),
Datetime(ref s) => write!(f, "{}", s),
Table(ref t) => {
let mut p = Printer { output: f, stack: Vec::new() };
p.print(t)
}
Array(ref a) => write!(f, "{}", a),
}
}
}
impl<'a, 'b> Printer<'a, 'b> {
2014-09-21 09:55:13 -05:00
fn print(&mut self, table: &'a TomlTable) -> fmt::Result {
for (k, v) in table.iter() {
match *v {
Table(..) => continue,
Array(ref a) => {
match a.as_slice().head() {
Some(&Table(..)) => continue,
_ => {}
}
}
_ => {}
}
try!(writeln!(self.output, "{} = {}", k, v));
}
for (k, v) in table.iter() {
match *v {
Table(ref inner) => {
self.stack.push(k.as_slice());
try!(writeln!(self.output, "\n[{}]",
self.stack.connect(".")));
try!(self.print(inner));
self.stack.pop();
}
Array(ref inner) => {
match inner.as_slice().head() {
Some(&Table(..)) => {}
_ => continue
}
self.stack.push(k.as_slice());
for inner in inner.iter() {
try!(writeln!(self.output, "\n[[{}]]",
self.stack.connect(".")));
match *inner {
Table(ref inner) => try!(self.print(inner)),
2014-10-29 20:45:18 -05:00
_ => panic!("non-heterogeneous toml array"),
}
}
self.stack.pop();
}
_ => {},
}
}
Ok(())
}
}
#[cfg(test)]
#[allow(warnings)]
mod tests {
2014-11-18 02:13:21 -06:00
use Value;
use Value::{String, Integer, Float, Boolean, Datetime, Array, Table};
2014-12-21 00:35:14 -06:00
use std::collections::BTreeMap;
macro_rules! map( ($($k:expr: $v:expr),*) => ({
2014-12-21 00:35:14 -06:00
let mut _m = BTreeMap::new();
2014-07-09 08:35:54 -05:00
$(_m.insert($k.to_string(), $v);)*
_m
}) );
#[test]
fn simple_show() {
2014-07-09 08:35:54 -05:00
assert_eq!(String("foo".to_string()).to_string().as_slice(),
"\"foo\"");
2014-07-09 08:35:54 -05:00
assert_eq!(Integer(10).to_string().as_slice(),
"10");
2014-07-09 08:35:54 -05:00
assert_eq!(Float(10.0).to_string().as_slice(),
"10.0");
2014-07-09 08:35:54 -05:00
assert_eq!(Float(2.4).to_string().as_slice(),
"2.4");
2014-07-09 08:35:54 -05:00
assert_eq!(Boolean(true).to_string().as_slice(),
"true");
2014-07-09 08:35:54 -05:00
assert_eq!(Datetime("test".to_string()).to_string().as_slice(),
"test");
2014-07-09 08:35:54 -05:00
assert_eq!(Array(vec![]).to_string().as_slice(),
"[]");
2014-07-09 08:35:54 -05:00
assert_eq!(Array(vec![Integer(1), Integer(2)]).to_string().as_slice(),
"[1, 2]");
}
#[test]
fn table() {
2014-07-09 08:35:54 -05:00
assert_eq!(Table(map! { }).to_string().as_slice(),
"");
2014-07-09 08:35:54 -05:00
assert_eq!(Table(map! { "test": Integer(2) }).to_string().as_slice(),
"test = 2\n");
assert_eq!(Table(map! {
"test": Integer(2),
"test2": Table(map! {
2014-07-09 08:35:54 -05:00
"test": String("wut".to_string())
})
2014-07-09 08:35:54 -05:00
}).to_string().as_slice(),
"test = 2\n\
\n\
[test2]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"test": Integer(2),
"test2": Table(map! {
2014-07-09 08:35:54 -05:00
"test": String("wut".to_string())
})
2014-07-09 08:35:54 -05:00
}).to_string().as_slice(),
"test = 2\n\
\n\
[test2]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"test": Integer(2),
"test2": Array(vec![Table(map! {
2014-07-09 08:35:54 -05:00
"test": String("wut".to_string())
})])
2014-07-09 08:35:54 -05:00
}).to_string().as_slice(),
"test = 2\n\
\n\
[[test2]]\n\
test = \"wut\"\n");
}
}