]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/builders.rs
Auto merge of #27505 - steveklabnik:exterminate_exterminate, r=brson
[rust.git] / src / libcore / fmt / builders.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use prelude::v1::*;
12 use fmt::{self, Write, FlagV1};
13
14 struct PadAdapter<'a, 'b: 'a> {
15     fmt: &'a mut fmt::Formatter<'b>,
16     on_newline: bool,
17 }
18
19 impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
20     fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> {
21         PadAdapter {
22             fmt: fmt,
23             on_newline: false,
24         }
25     }
26 }
27
28 impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
29     fn write_str(&mut self, mut s: &str) -> fmt::Result {
30         while !s.is_empty() {
31             if self.on_newline {
32                 try!(self.fmt.write_str("    "));
33             }
34
35             let split = match s.find('\n') {
36                 Some(pos) => {
37                     self.on_newline = true;
38                     pos + 1
39                 }
40                 None => {
41                     self.on_newline = false;
42                     s.len()
43                 }
44             };
45             try!(self.fmt.write_str(&s[..split]));
46             s = &s[split..];
47         }
48
49         Ok(())
50     }
51 }
52
53 /// A struct to help with `fmt::Debug` implementations.
54 ///
55 /// Constructed by the `Formatter::debug_struct` method.
56 #[must_use]
57 #[stable(feature = "debug_builders", since = "1.2.0")]
58 pub struct DebugStruct<'a, 'b: 'a> {
59     fmt: &'a mut fmt::Formatter<'b>,
60     result: fmt::Result,
61     has_fields: bool,
62 }
63
64 pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str)
65                                 -> DebugStruct<'a, 'b> {
66     let result = fmt.write_str(name);
67     DebugStruct {
68         fmt: fmt,
69         result: result,
70         has_fields: false,
71     }
72 }
73
74 impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
75     /// Adds a new field to the generated struct output.
76     #[stable(feature = "debug_builders", since = "1.2.0")]
77     pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
78         self.result = self.result.and_then(|_| {
79             let prefix = if self.has_fields {
80                 ","
81             } else {
82                 " {"
83             };
84
85             if self.is_pretty() {
86                 let mut writer = PadAdapter::new(self.fmt);
87                 fmt::write(&mut writer, format_args!("{}\n{}: {:#?}", prefix, name, value))
88             } else {
89                 write!(self.fmt, "{} {}: {:?}", prefix, name, value)
90             }
91         });
92
93         self.has_fields = true;
94         self
95     }
96
97     /// Finishes output and returns any error encountered.
98     #[stable(feature = "debug_builders", since = "1.2.0")]
99     pub fn finish(&mut self) -> fmt::Result {
100         if self.has_fields {
101             self.result = self.result.and_then(|_| {
102                 if self.is_pretty() {
103                     self.fmt.write_str("\n}")
104                 } else {
105                     self.fmt.write_str(" }")
106                 }
107             });
108         }
109         self.result
110     }
111
112     fn is_pretty(&self) -> bool {
113         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
114     }
115 }
116
117 /// A struct to help with `fmt::Debug` implementations.
118 ///
119 /// Constructed by the `Formatter::debug_tuple` method.
120 #[must_use]
121 #[stable(feature = "debug_builders", since = "1.2.0")]
122 pub struct DebugTuple<'a, 'b: 'a> {
123     fmt: &'a mut fmt::Formatter<'b>,
124     result: fmt::Result,
125     has_fields: bool,
126 }
127
128 pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
129     let result = fmt.write_str(name);
130     DebugTuple {
131         fmt: fmt,
132         result: result,
133         has_fields: false,
134     }
135 }
136
137 impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
138     /// Adds a new field to the generated tuple struct output.
139     #[stable(feature = "debug_builders", since = "1.2.0")]
140     pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
141         self.result = self.result.and_then(|_| {
142             let (prefix, space) = if self.has_fields {
143                 (",", " ")
144             } else {
145                 ("(", "")
146             };
147
148             if self.is_pretty() {
149                 let mut writer = PadAdapter::new(self.fmt);
150                 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
151             } else {
152                 write!(self.fmt, "{}{}{:?}", prefix, space, value)
153             }
154         });
155
156         self.has_fields = true;
157         self
158     }
159
160     /// Finishes output and returns any error encountered.
161     #[stable(feature = "debug_builders", since = "1.2.0")]
162     pub fn finish(&mut self) -> fmt::Result {
163         if self.has_fields {
164             self.result = self.result.and_then(|_| {
165                 if self.is_pretty() {
166                     self.fmt.write_str("\n)")
167                 } else {
168                     self.fmt.write_str(")")
169                 }
170             });
171         }
172         self.result
173     }
174
175     fn is_pretty(&self) -> bool {
176         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
177     }
178
179     /// Returns the wrapped `Formatter`.
180     #[unstable(feature = "debug_builder_formatter", reason = "recently added")]
181     pub fn formatter(&mut self) -> &mut fmt::Formatter<'b> {
182         &mut self.fmt
183     }
184 }
185
186 struct DebugInner<'a, 'b: 'a> {
187     fmt: &'a mut fmt::Formatter<'b>,
188     result: fmt::Result,
189     has_fields: bool,
190 }
191
192 impl<'a, 'b: 'a> DebugInner<'a, 'b> {
193     fn entry(&mut self, entry: &fmt::Debug) {
194         self.result = self.result.and_then(|_| {
195             if self.is_pretty() {
196                 let mut writer = PadAdapter::new(self.fmt);
197                 let prefix = if self.has_fields { "," } else { "" };
198                 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
199             } else {
200                 let prefix = if self.has_fields { ", " } else { "" };
201                 write!(self.fmt, "{}{:?}", prefix, entry)
202             }
203         });
204
205         self.has_fields = true;
206     }
207
208     pub fn finish(&mut self) {
209         let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
210         self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
211     }
212
213     fn is_pretty(&self) -> bool {
214         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
215     }
216 }
217
218 /// A struct to help with `fmt::Debug` implementations.
219 ///
220 /// Constructed by the `Formatter::debug_set` method.
221 #[must_use]
222 #[stable(feature = "debug_builders", since = "1.2.0")]
223 pub struct DebugSet<'a, 'b: 'a> {
224     inner: DebugInner<'a, 'b>,
225 }
226
227 pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
228     let result = write!(fmt, "{{");
229     DebugSet {
230         inner: DebugInner {
231             fmt: fmt,
232             result: result,
233             has_fields: false,
234         }
235     }
236 }
237
238 impl<'a, 'b: 'a> DebugSet<'a, 'b> {
239     /// Adds a new entry to the set output.
240     #[stable(feature = "debug_builders", since = "1.2.0")]
241     pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
242         self.inner.entry(entry);
243         self
244     }
245
246     /// Adds the contents of an iterator of entries to the set output.
247     #[stable(feature = "debug_builders", since = "1.2.0")]
248     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b>
249             where D: fmt::Debug, I: IntoIterator<Item=D> {
250         for entry in entries {
251             self.entry(&entry);
252         }
253         self
254     }
255
256     /// Finishes output and returns any error encountered.
257     #[stable(feature = "debug_builders", since = "1.2.0")]
258     pub fn finish(&mut self) -> fmt::Result {
259         self.inner.finish();
260         self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
261     }
262 }
263
264 /// A struct to help with `fmt::Debug` implementations.
265 ///
266 /// Constructed by the `Formatter::debug_list` method.
267 #[must_use]
268 #[stable(feature = "debug_builders", since = "1.2.0")]
269 pub struct DebugList<'a, 'b: 'a> {
270     inner: DebugInner<'a, 'b>,
271 }
272
273 pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
274     let result = write!(fmt, "[");
275     DebugList {
276         inner: DebugInner {
277             fmt: fmt,
278             result: result,
279             has_fields: false,
280         }
281     }
282 }
283
284 impl<'a, 'b: 'a> DebugList<'a, 'b> {
285     /// Adds a new entry to the list output.
286     #[stable(feature = "debug_builders", since = "1.2.0")]
287     pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
288         self.inner.entry(entry);
289         self
290     }
291
292     /// Adds the contents of an iterator of entries to the list output.
293     #[stable(feature = "debug_builders", since = "1.2.0")]
294     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b>
295             where D: fmt::Debug, I: IntoIterator<Item=D> {
296         for entry in entries {
297             self.entry(&entry);
298         }
299         self
300     }
301
302     /// Finishes output and returns any error encountered.
303     #[stable(feature = "debug_builders", since = "1.2.0")]
304     pub fn finish(&mut self) -> fmt::Result {
305         self.inner.finish();
306         self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
307     }
308 }
309
310 /// A struct to help with `fmt::Debug` implementations.
311 ///
312 /// Constructed by the `Formatter::debug_map` method.
313 #[must_use]
314 #[stable(feature = "debug_builders", since = "1.2.0")]
315 pub struct DebugMap<'a, 'b: 'a> {
316     fmt: &'a mut fmt::Formatter<'b>,
317     result: fmt::Result,
318     has_fields: bool,
319 }
320
321 pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
322     let result = write!(fmt, "{{");
323     DebugMap {
324         fmt: fmt,
325         result: result,
326         has_fields: false,
327     }
328 }
329
330 impl<'a, 'b: 'a> DebugMap<'a, 'b> {
331     /// Adds a new entry to the map output.
332     #[stable(feature = "debug_builders", since = "1.2.0")]
333     pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
334         self.result = self.result.and_then(|_| {
335             if self.is_pretty() {
336                 let mut writer = PadAdapter::new(self.fmt);
337                 let prefix = if self.has_fields { "," } else { "" };
338                 fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
339             } else {
340                 let prefix = if self.has_fields { ", " } else { "" };
341                 write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
342             }
343         });
344
345         self.has_fields = true;
346         self
347     }
348
349     /// Adds the contents of an iterator of entries to the map output.
350     #[stable(feature = "debug_builders", since = "1.2.0")]
351     pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b>
352             where K: fmt::Debug, V: fmt::Debug, I: IntoIterator<Item=(K, V)> {
353         for (k, v) in entries {
354             self.entry(&k, &v);
355         }
356         self
357     }
358
359     /// Finishes output and returns any error encountered.
360     #[stable(feature = "debug_builders", since = "1.2.0")]
361     pub fn finish(&mut self) -> fmt::Result {
362         let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
363         self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
364     }
365
366     fn is_pretty(&self) -> bool {
367         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
368     }
369 }