]> git.proxmox.com Git - rustc.git/blame - src/vendor/toml/src/value/display.rs
New upstream version 1.18.0+dfsg1
[rustc.git] / src / vendor / toml / src / value / display.rs
CommitLineData
476ff2be
SL
1use std::fmt;
2
3use Table as TomlTable;
4use Value::{self, String, Integer, Float, Boolean, Datetime, Array, Table};
5
6struct Printer<'a, 'b:'a> {
7 output: &'a mut fmt::Formatter<'b>,
8 stack: Vec<&'a str>,
9}
10
11struct Key<'a>(&'a [&'a str]);
12
13impl fmt::Display for Value {
14 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 match *self {
16 String(ref s) => write_str(f, s),
17 Integer(i) => write!(f, "{}", i),
18 Float(fp) => {
19 try!(write!(f, "{}", fp));
20 if fp % 1.0 == 0.0 { try!(write!(f, ".0")) }
21 Ok(())
22 }
23 Boolean(b) => write!(f, "{}", b),
24 Datetime(ref s) => write!(f, "{}", s),
25 Table(ref t) => {
26 let mut p = Printer { output: f, stack: Vec::new() };
27 p.print(t)
28 }
29 Array(ref a) => {
30 try!(write!(f, "["));
31 for (i, v) in a.iter().enumerate() {
32 if i != 0 { try!(write!(f, ", ")); }
33 try!(write!(f, "{}", v));
34 }
35 write!(f, "]")
36 }
37 }
38 }
39}
40
41fn write_str(f: &mut fmt::Formatter, s: &str) -> fmt::Result {
42 try!(write!(f, "\""));
43 for ch in s.chars() {
44 match ch {
45 '\u{8}' => try!(write!(f, "\\b")),
46 '\u{9}' => try!(write!(f, "\\t")),
47 '\u{a}' => try!(write!(f, "\\n")),
48 '\u{c}' => try!(write!(f, "\\f")),
49 '\u{d}' => try!(write!(f, "\\r")),
50 '\u{22}' => try!(write!(f, "\\\"")),
51 '\u{5c}' => try!(write!(f, "\\\\")),
8bb4bdeb
XL
52 c if c < '\u{1f}' => {
53 try!(write!(f, "\\u{:04}", ch as u32))
54 }
476ff2be
SL
55 ch => try!(write!(f, "{}", ch)),
56 }
57 }
58 write!(f, "\"")
59}
60
61impl<'a, 'b> Printer<'a, 'b> {
62 fn print(&mut self, table: &'a TomlTable) -> fmt::Result {
8bb4bdeb 63 let mut space_out_first = false;
476ff2be
SL
64 for (k, v) in table.iter() {
65 match *v {
66 Table(..) => continue,
67 Array(ref a) => {
68 if let Some(&Table(..)) = a.first() {
69 continue;
70 }
71 }
72 _ => {}
73 }
8bb4bdeb 74 space_out_first = true;
476ff2be
SL
75 try!(writeln!(self.output, "{} = {}", Key(&[k]), v));
76 }
8bb4bdeb 77 for (i, (k, v)) in table.iter().enumerate() {
476ff2be
SL
78 match *v {
79 Table(ref inner) => {
80 self.stack.push(k);
8bb4bdeb
XL
81 if space_out_first || i != 0 {
82 try!(write!(self.output, "\n"));
83 }
84 try!(writeln!(self.output, "[{}]", Key(&self.stack)));
476ff2be
SL
85 try!(self.print(inner));
86 self.stack.pop();
87 }
88 Array(ref inner) => {
89 match inner.first() {
90 Some(&Table(..)) => {}
91 _ => continue
92 }
93 self.stack.push(k);
8bb4bdeb
XL
94 for (j, inner) in inner.iter().enumerate() {
95 if space_out_first || i != 0 || j != 0 {
96 try!(write!(self.output, "\n"));
97 }
98 try!(writeln!(self.output, "[[{}]]", Key(&self.stack)));
476ff2be
SL
99 match *inner {
100 Table(ref inner) => try!(self.print(inner)),
101 _ => panic!("non-heterogeneous toml array"),
102 }
103 }
104 self.stack.pop();
105 }
106 _ => {},
107 }
108 }
109 Ok(())
110 }
111}
112
113impl<'a> fmt::Display for Key<'a> {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 for (i, part) in self.0.iter().enumerate() {
116 if i != 0 { try!(write!(f, ".")); }
117 let ok = part.chars().all(|c| {
118 match c {
119 'a' ... 'z' |
120 'A' ... 'Z' |
121 '0' ... '9' |
122 '-' | '_' => true,
123 _ => false,
124 }
125 });
126 if ok {
127 try!(write!(f, "{}", part));
128 } else {
129 try!(write_str(f, part));
130 }
131 }
132 Ok(())
133 }
134}