]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/builders.rs
Changed issue number to 36105
[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, 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                 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             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 #[allow(missing_debug_implementations)]
58 #[stable(feature = "debug_builders", since = "1.2.0")]
59 pub struct DebugStruct<'a, 'b: 'a> {
60     fmt: &'a mut fmt::Formatter<'b>,
61     result: fmt::Result,
62     has_fields: bool,
63 }
64
65 pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
66                                 name: &str)
67                                 -> DebugStruct<'a, 'b> {
68     let result = fmt.write_str(name);
69     DebugStruct {
70         fmt: fmt,
71         result: result,
72         has_fields: false,
73     }
74 }
75
76 impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
77     /// Adds a new field to the generated struct output.
78     #[stable(feature = "debug_builders", since = "1.2.0")]
79     pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut 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,
90                            format_args!("{}\n{}: {:#?}", prefix, name, value))
91             } else {
92                 write!(self.fmt, "{} {}: {:?}", prefix, name, value)
93             }
94         });
95
96         self.has_fields = true;
97         self
98     }
99
100     /// Finishes output and returns any error encountered.
101     #[stable(feature = "debug_builders", since = "1.2.0")]
102     pub fn finish(&mut self) -> fmt::Result {
103         if self.has_fields {
104             self.result = self.result.and_then(|_| {
105                 if self.is_pretty() {
106                     self.fmt.write_str("\n}")
107                 } else {
108                     self.fmt.write_str(" }")
109                 }
110             });
111         }
112         self.result
113     }
114
115     fn is_pretty(&self) -> bool {
116         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
117     }
118 }
119
120 /// A struct to help with `fmt::Debug` implementations.
121 ///
122 /// Constructed by the `Formatter::debug_tuple` method.
123 #[must_use]
124 #[allow(missing_debug_implementations)]
125 #[stable(feature = "debug_builders", since = "1.2.0")]
126 pub struct DebugTuple<'a, 'b: 'a> {
127     fmt: &'a mut fmt::Formatter<'b>,
128     result: fmt::Result,
129     fields: usize,
130     empty_name: bool,
131 }
132
133 pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
134     let result = fmt.write_str(name);
135     DebugTuple {
136         fmt: fmt,
137         result: result,
138         fields: 0,
139         empty_name: name.is_empty(),
140     }
141 }
142
143 impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
144     /// Adds a new field to the generated tuple struct output.
145     #[stable(feature = "debug_builders", since = "1.2.0")]
146     pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
147         self.result = self.result.and_then(|_| {
148             let (prefix, space) = if self.fields > 0 {
149                 (",", " ")
150             } else {
151                 ("(", "")
152             };
153
154             if self.is_pretty() {
155                 let mut writer = PadAdapter::new(self.fmt);
156                 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
157             } else {
158                 write!(self.fmt, "{}{}{:?}", prefix, space, value)
159             }
160         });
161
162         self.fields += 1;
163         self
164     }
165
166     /// Finishes output and returns any error encountered.
167     #[stable(feature = "debug_builders", since = "1.2.0")]
168     pub fn finish(&mut self) -> fmt::Result {
169         if self.fields > 0 {
170             self.result = self.result.and_then(|_| {
171                 if self.is_pretty() {
172                     self.fmt.write_str("\n")?;
173                 }
174                 if self.fields == 1 && self.empty_name {
175                     self.fmt.write_str(",")?;
176                 }
177                 self.fmt.write_str(")")
178             });
179         }
180         self.result
181     }
182
183     fn is_pretty(&self) -> bool {
184         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
185     }
186 }
187
188 struct DebugInner<'a, 'b: 'a> {
189     fmt: &'a mut fmt::Formatter<'b>,
190     result: fmt::Result,
191     has_fields: bool,
192 }
193
194 impl<'a, 'b: 'a> DebugInner<'a, 'b> {
195     fn entry(&mut self, entry: &fmt::Debug) {
196         self.result = self.result.and_then(|_| {
197             if self.is_pretty() {
198                 let mut writer = PadAdapter::new(self.fmt);
199                 let prefix = if self.has_fields {
200                     ","
201                 } else {
202                     ""
203                 };
204                 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
205             } else {
206                 let prefix = if self.has_fields {
207                     ", "
208                 } else {
209                     ""
210                 };
211                 write!(self.fmt, "{}{:?}", prefix, entry)
212             }
213         });
214
215         self.has_fields = true;
216     }
217
218     pub fn finish(&mut self) {
219         let prefix = if self.is_pretty() && self.has_fields {
220             "\n"
221         } else {
222             ""
223         };
224         self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
225     }
226
227     fn is_pretty(&self) -> bool {
228         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
229     }
230 }
231
232 /// A struct to help with `fmt::Debug` implementations.
233 ///
234 /// Constructed by the `Formatter::debug_set` method.
235 #[must_use]
236 #[allow(missing_debug_implementations)]
237 #[stable(feature = "debug_builders", since = "1.2.0")]
238 pub struct DebugSet<'a, 'b: 'a> {
239     inner: DebugInner<'a, 'b>,
240 }
241
242 pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
243     let result = write!(fmt, "{{");
244     DebugSet {
245         inner: DebugInner {
246             fmt: fmt,
247             result: result,
248             has_fields: false,
249         },
250     }
251 }
252
253 impl<'a, 'b: 'a> DebugSet<'a, 'b> {
254     /// Adds a new entry to the set output.
255     #[stable(feature = "debug_builders", since = "1.2.0")]
256     pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
257         self.inner.entry(entry);
258         self
259     }
260
261     /// Adds the contents of an iterator of entries to the set output.
262     #[stable(feature = "debug_builders", since = "1.2.0")]
263     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b>
264         where D: fmt::Debug,
265               I: IntoIterator<Item = D>
266     {
267         for entry in entries {
268             self.entry(&entry);
269         }
270         self
271     }
272
273     /// Finishes output and returns any error encountered.
274     #[stable(feature = "debug_builders", since = "1.2.0")]
275     pub fn finish(&mut self) -> fmt::Result {
276         self.inner.finish();
277         self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
278     }
279 }
280
281 /// A struct to help with `fmt::Debug` implementations.
282 ///
283 /// Constructed by the `Formatter::debug_list` method.
284 #[must_use]
285 #[allow(missing_debug_implementations)]
286 #[stable(feature = "debug_builders", since = "1.2.0")]
287 pub struct DebugList<'a, 'b: 'a> {
288     inner: DebugInner<'a, 'b>,
289 }
290
291 pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
292     let result = write!(fmt, "[");
293     DebugList {
294         inner: DebugInner {
295             fmt: fmt,
296             result: result,
297             has_fields: false,
298         },
299     }
300 }
301
302 impl<'a, 'b: 'a> DebugList<'a, 'b> {
303     /// Adds a new entry to the list output.
304     #[stable(feature = "debug_builders", since = "1.2.0")]
305     pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
306         self.inner.entry(entry);
307         self
308     }
309
310     /// Adds the contents of an iterator of entries to the list output.
311     #[stable(feature = "debug_builders", since = "1.2.0")]
312     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b>
313         where D: fmt::Debug,
314               I: IntoIterator<Item = D>
315     {
316         for entry in entries {
317             self.entry(&entry);
318         }
319         self
320     }
321
322     /// Finishes output and returns any error encountered.
323     #[stable(feature = "debug_builders", since = "1.2.0")]
324     pub fn finish(&mut self) -> fmt::Result {
325         self.inner.finish();
326         self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
327     }
328 }
329
330 /// A struct to help with `fmt::Debug` implementations.
331 ///
332 /// Constructed by the `Formatter::debug_map` method.
333 #[must_use]
334 #[allow(missing_debug_implementations)]
335 #[stable(feature = "debug_builders", since = "1.2.0")]
336 pub struct DebugMap<'a, 'b: 'a> {
337     fmt: &'a mut fmt::Formatter<'b>,
338     result: fmt::Result,
339     has_fields: bool,
340 }
341
342 pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
343     let result = write!(fmt, "{{");
344     DebugMap {
345         fmt: fmt,
346         result: result,
347         has_fields: false,
348     }
349 }
350
351 impl<'a, 'b: 'a> DebugMap<'a, 'b> {
352     /// Adds a new entry to the map output.
353     #[stable(feature = "debug_builders", since = "1.2.0")]
354     pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
355         self.result = self.result.and_then(|_| {
356             if self.is_pretty() {
357                 let mut writer = PadAdapter::new(self.fmt);
358                 let prefix = if self.has_fields {
359                     ","
360                 } else {
361                     ""
362                 };
363                 fmt::write(&mut writer,
364                            format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
365             } else {
366                 let prefix = if self.has_fields {
367                     ", "
368                 } else {
369                     ""
370                 };
371                 write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
372             }
373         });
374
375         self.has_fields = true;
376         self
377     }
378
379     /// Adds the contents of an iterator of entries to the map output.
380     #[stable(feature = "debug_builders", since = "1.2.0")]
381     pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b>
382         where K: fmt::Debug,
383               V: fmt::Debug,
384               I: IntoIterator<Item = (K, V)>
385     {
386         for (k, v) in entries {
387             self.entry(&k, &v);
388         }
389         self
390     }
391
392     /// Finishes output and returns any error encountered.
393     #[stable(feature = "debug_builders", since = "1.2.0")]
394     pub fn finish(&mut self) -> fmt::Result {
395         let prefix = if self.is_pretty() && self.has_fields {
396             "\n"
397         } else {
398             ""
399         };
400         self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
401     }
402
403     fn is_pretty(&self) -> bool {
404         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
405     }
406 }