1use std::fmt::{self, Write};
12
13#[cfg(test)]
14mod test;
15
16const ALTERNATE_MASK: u32 = 1 << 2;
17
18struct PadAdapter<'a, 'b: 'a> {
19 fmt: &'a mut fmt::Formatter<'b>,
20 on_newline: bool,
21}
22
23impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
24 fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> {
25 PadAdapter {
26 fmt: fmt,
27 on_newline: false,
28 }
29 }
30}
31
32impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
33 fn write_str(&mut self, mut s: &str) -> fmt::Result {
34 while !s.is_empty() {
35 if self.on_newline {
36 try!(self.fmt.write_str(" "));
37 }
38
39 let split = match s.find('\n') {
40 Some(pos) => {
41 self.on_newline = true;
42 pos + 1
43 }
44 None => {
45 self.on_newline = false;
46 s.len()
47 }
48 };
49 try!(self.fmt.write_str(&s[..split]));
50 s = &s[split..];
51 }
52
53 Ok(())
54 }
55}
56
57#[must_use]
61pub struct DebugStruct<'a, 'b: 'a> {
62 fmt: &'a mut fmt::Formatter<'b>,
63 result: fmt::Result,
64 has_fields: bool,
65}
66
67impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
68 pub fn new(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugStruct<'a, 'b> {
70 let result = fmt.write_str(name);
71 DebugStruct {
72 fmt: fmt,
73 result: result,
74 has_fields: false,
75 }
76 }
77
78 pub fn field(mut self, name: &str, value: &fmt::Debug) -> DebugStruct<'a, 'b> {
80 self.result = self.result.and_then(|_| {
81 let prefix = if self.has_fields {
82 ","
83 } else {
84 " {"
85 };
86
87 if self.is_pretty() {
88 let mut writer = PadAdapter::new(self.fmt);
89 fmt::write(&mut writer, format_args!("{}\n{}: {:#?}", prefix, name, value))
90 } else {
91 write!(self.fmt, "{} {}: {:?}", prefix, name, value)
92 }
93 });
94
95 self.has_fields = true;
96 self
97 }
98
99 pub fn finish(mut self) -> fmt::Result {
102 if self.has_fields {
103 self.result = self.result.and_then(|_| {
104 if self.is_pretty() {
105 self.fmt.write_str("\n}")
106 } else {
107 self.fmt.write_str(" }")
108 }
109 });
110 }
111 self.result
112 }
113
114 fn is_pretty(&self) -> bool {
115 self.fmt.flags() & ALTERNATE_MASK != 0
116 }
117}
118
119#[must_use]
121pub struct DebugTuple<'a, 'b: 'a> {
122 fmt: &'a mut fmt::Formatter<'b>,
123 result: fmt::Result,
124 has_fields: bool,
125}
126
127impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
128 pub fn new(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
130 let result = fmt.write_str(name);
131 DebugTuple {
132 fmt: fmt,
133 result: result,
134 has_fields: false,
135 }
136 }
137
138 pub fn field(mut self, value: &fmt::Debug) -> DebugTuple<'a, 'b> {
140 self.result = self.result.and_then(|_| {
141 let (prefix, space) = if self.has_fields {
142 (",", " ")
143 } else {
144 ("(", "")
145 };
146
147 if self.is_pretty() {
148 let mut writer = PadAdapter::new(self.fmt);
149 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
150 } else {
151 write!(self.fmt, "{}{}{:?}", prefix, space, value)
152 }
153 });
154
155 self.has_fields = true;
156 self
157 }
158
159 pub fn finish(mut self) -> fmt::Result {
162 if self.has_fields {
163 self.result = self.result.and_then(|_| {
164 if self.is_pretty() {
165 self.fmt.write_str("\n)")
166 } else {
167 self.fmt.write_str(")")
168 }
169 });
170 }
171 self.result
172 }
173
174 fn is_pretty(&self) -> bool {
175 self.fmt.flags() & ALTERNATE_MASK != 0
176 }
177}
178
179struct DebugInner<'a, 'b: 'a> {
180 fmt: &'a mut fmt::Formatter<'b>,
181 result: fmt::Result,
182 has_fields: bool,
183}
184
185impl<'a, 'b: 'a> DebugInner<'a, 'b> {
186 fn entry(&mut self, entry: &fmt::Debug) {
187 self.result = self.result.and_then(|_| {
188 if self.is_pretty() {
189 let mut writer = PadAdapter::new(self.fmt);
190 let prefix = if self.has_fields { "," } else { "" };
191 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
192 } else {
193 let prefix = if self.has_fields { ", " } else { "" };
194 write!(self.fmt, "{}{:?}", prefix, entry)
195 }
196 });
197
198 self.has_fields = true;
199 }
200
201 pub fn finish(&mut self) {
202 let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
203 self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
204 }
205
206 fn is_pretty(&self) -> bool {
207 self.fmt.flags() & ALTERNATE_MASK != 0
208 }
209}
210
211#[must_use]
213pub struct DebugSet<'a, 'b: 'a> {
214 inner: DebugInner<'a, 'b>,
215}
216
217impl<'a, 'b: 'a> DebugSet<'a, 'b> {
218 pub fn new(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
220 let result = write!(fmt, "{{");
221 DebugSet {
222 inner: DebugInner {
223 fmt: fmt,
224 result: result,
225 has_fields: false,
226 }
227 }
228 }
229
230 pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> {
232 self.inner.entry(entry);
233 self
234 }
235
236 pub fn finish(mut self) -> fmt::Result {
239 self.inner.finish();
240 self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
241 }
242}
243
244#[must_use]
246pub struct DebugList<'a, 'b: 'a> {
247 inner: DebugInner<'a, 'b>,
248}
249
250impl<'a, 'b: 'a> DebugList<'a, 'b> {
251 pub fn new(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
253 let result = write!(fmt, "[");
254 DebugList {
255 inner: DebugInner {
256 fmt: fmt,
257 result: result,
258 has_fields: false,
259 }
260 }
261 }
262
263 pub fn entry(mut self, entry: &fmt::Debug) -> DebugList<'a, 'b> {
265 self.inner.entry(entry);
266 self
267 }
268
269 pub fn finish(mut self) -> fmt::Result {
272 self.inner.finish();
273 self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
274 }
275}
276
277#[must_use]
279pub struct DebugMap<'a, 'b: 'a> {
280 fmt: &'a mut fmt::Formatter<'b>,
281 result: fmt::Result,
282 has_fields: bool,
283}
284
285impl<'a, 'b: 'a> DebugMap<'a, 'b> {
286 pub fn new(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
288 let result = write!(fmt, "{{");
289 DebugMap {
290 fmt: fmt,
291 result: result,
292 has_fields: false,
293 }
294 }
295
296 pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> {
298 self.result = self.result.and_then(|_| {
299 if self.is_pretty() {
300 let mut writer = PadAdapter::new(self.fmt);
301 let prefix = if self.has_fields { "," } else { "" };
302 fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
303 } else {
304 let prefix = if self.has_fields { ", " } else { "" };
305 write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
306 }
307 });
308
309 self.has_fields = true;
310 self
311 }
312
313 pub fn finish(self) -> fmt::Result {
316 let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
317 self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
318 }
319
320 fn is_pretty(&self) -> bool {
321 self.fmt.flags() & ALTERNATE_MASK != 0
322 }
323}