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