]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/builders.rs
Rollup merge of #28878 - sourcefrog:doc-links, r=steveklabnik
[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                issue = "27782")]
182     pub fn formatter(&mut self) -> &mut fmt::Formatter<'b> {
183         &mut self.fmt
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 { "," } else { "" };
199                 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
200             } else {
201                 let prefix = if self.has_fields { ", " } else { "" };
202                 write!(self.fmt, "{}{:?}", prefix, entry)
203             }
204         });
205
206         self.has_fields = true;
207     }
208
209     pub fn finish(&mut self) {
210         let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
211         self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
212     }
213
214     fn is_pretty(&self) -> bool {
215         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
216     }
217 }
218
219 /// A struct to help with `fmt::Debug` implementations.
220 ///
221 /// Constructed by the `Formatter::debug_set` method.
222 #[must_use]
223 #[stable(feature = "debug_builders", since = "1.2.0")]
224 pub struct DebugSet<'a, 'b: 'a> {
225     inner: DebugInner<'a, 'b>,
226 }
227
228 pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
229     let result = write!(fmt, "{{");
230     DebugSet {
231         inner: DebugInner {
232             fmt: fmt,
233             result: result,
234             has_fields: false,
235         }
236     }
237 }
238
239 impl<'a, 'b: 'a> DebugSet<'a, 'b> {
240     /// Adds a new entry to the set output.
241     #[stable(feature = "debug_builders", since = "1.2.0")]
242     pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
243         self.inner.entry(entry);
244         self
245     }
246
247     /// Adds the contents of an iterator of entries to the set output.
248     #[stable(feature = "debug_builders", since = "1.2.0")]
249     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b>
250             where D: fmt::Debug, I: IntoIterator<Item=D> {
251         for entry in entries {
252             self.entry(&entry);
253         }
254         self
255     }
256
257     /// Finishes output and returns any error encountered.
258     #[stable(feature = "debug_builders", since = "1.2.0")]
259     pub fn finish(&mut self) -> fmt::Result {
260         self.inner.finish();
261         self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
262     }
263 }
264
265 /// A struct to help with `fmt::Debug` implementations.
266 ///
267 /// Constructed by the `Formatter::debug_list` method.
268 #[must_use]
269 #[stable(feature = "debug_builders", since = "1.2.0")]
270 pub struct DebugList<'a, 'b: 'a> {
271     inner: DebugInner<'a, 'b>,
272 }
273
274 pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
275     let result = write!(fmt, "[");
276     DebugList {
277         inner: DebugInner {
278             fmt: fmt,
279             result: result,
280             has_fields: false,
281         }
282     }
283 }
284
285 impl<'a, 'b: 'a> DebugList<'a, 'b> {
286     /// Adds a new entry to the list output.
287     #[stable(feature = "debug_builders", since = "1.2.0")]
288     pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
289         self.inner.entry(entry);
290         self
291     }
292
293     /// Adds the contents of an iterator of entries to the list output.
294     #[stable(feature = "debug_builders", since = "1.2.0")]
295     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b>
296             where D: fmt::Debug, I: IntoIterator<Item=D> {
297         for entry in entries {
298             self.entry(&entry);
299         }
300         self
301     }
302
303     /// Finishes output and returns any error encountered.
304     #[stable(feature = "debug_builders", since = "1.2.0")]
305     pub fn finish(&mut self) -> fmt::Result {
306         self.inner.finish();
307         self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
308     }
309 }
310
311 /// A struct to help with `fmt::Debug` implementations.
312 ///
313 /// Constructed by the `Formatter::debug_map` method.
314 #[must_use]
315 #[stable(feature = "debug_builders", since = "1.2.0")]
316 pub struct DebugMap<'a, 'b: 'a> {
317     fmt: &'a mut fmt::Formatter<'b>,
318     result: fmt::Result,
319     has_fields: bool,
320 }
321
322 pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
323     let result = write!(fmt, "{{");
324     DebugMap {
325         fmt: fmt,
326         result: result,
327         has_fields: false,
328     }
329 }
330
331 impl<'a, 'b: 'a> DebugMap<'a, 'b> {
332     /// Adds a new entry to the map output.
333     #[stable(feature = "debug_builders", since = "1.2.0")]
334     pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
335         self.result = self.result.and_then(|_| {
336             if self.is_pretty() {
337                 let mut writer = PadAdapter::new(self.fmt);
338                 let prefix = if self.has_fields { "," } else { "" };
339                 fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
340             } else {
341                 let prefix = if self.has_fields { ", " } else { "" };
342                 write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
343             }
344         });
345
346         self.has_fields = true;
347         self
348     }
349
350     /// Adds the contents of an iterator of entries to the map output.
351     #[stable(feature = "debug_builders", since = "1.2.0")]
352     pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b>
353             where K: fmt::Debug, V: fmt::Debug, I: IntoIterator<Item=(K, V)> {
354         for (k, v) in entries {
355             self.entry(&k, &v);
356         }
357         self
358     }
359
360     /// Finishes output and returns any error encountered.
361     #[stable(feature = "debug_builders", since = "1.2.0")]
362     pub fn finish(&mut self) -> fmt::Result {
363         let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
364         self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
365     }
366
367     fn is_pretty(&self) -> bool {
368         self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
369     }
370 }