]> git.proxmox.com Git - rustc.git/blame - src/libcore/fmt/builders.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / libcore / fmt / builders.rs
CommitLineData
c34b1796
AL
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
11use prelude::*;
12use fmt::{self, Write, FlagV1};
13
14struct PadAdapter<'a, 'b: 'a> {
15 fmt: &'a mut fmt::Formatter<'b>,
16 on_newline: bool,
17}
18
19impl<'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
28impl<'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]
62682a34 57#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
58pub struct DebugStruct<'a, 'b: 'a> {
59 fmt: &'a mut fmt::Formatter<'b>,
60 result: fmt::Result,
61 has_fields: bool,
62}
63
64pub 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
74impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
75 /// Adds a new field to the generated struct output.
62682a34
SL
76 #[stable(feature = "debug_builders", since = "1.2.0")]
77 pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
c34b1796
AL
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
62682a34
SL
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 {
c34b1796
AL
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]
62682a34 121#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
122pub struct DebugTuple<'a, 'b: 'a> {
123 fmt: &'a mut fmt::Formatter<'b>,
124 result: fmt::Result,
125 has_fields: bool,
126}
127
128pub 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
137impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
138 /// Adds a new field to the generated tuple struct output.
62682a34
SL
139 #[stable(feature = "debug_builders", since = "1.2.0")]
140 pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
c34b1796
AL
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
62682a34
SL
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 {
c34b1796
AL
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 }
c1a9b12d
SL
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 }
c34b1796
AL
184}
185
186struct DebugInner<'a, 'b: 'a> {
187 fmt: &'a mut fmt::Formatter<'b>,
188 result: fmt::Result,
189 has_fields: bool,
190}
191
192impl<'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]
62682a34 222#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
223pub struct DebugSet<'a, 'b: 'a> {
224 inner: DebugInner<'a, 'b>,
225}
226
227pub 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
238impl<'a, 'b: 'a> DebugSet<'a, 'b> {
239 /// Adds a new entry to the set output.
62682a34
SL
240 #[stable(feature = "debug_builders", since = "1.2.0")]
241 pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
c34b1796
AL
242 self.inner.entry(entry);
243 self
244 }
245
62682a34
SL
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 {
c34b1796
AL
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]
62682a34 268#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
269pub struct DebugList<'a, 'b: 'a> {
270 inner: DebugInner<'a, 'b>,
271}
272
273pub 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
284impl<'a, 'b: 'a> DebugList<'a, 'b> {
62682a34
SL
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> {
c34b1796
AL
288 self.inner.entry(entry);
289 self
290 }
291
62682a34
SL
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 {
c34b1796
AL
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]
62682a34 314#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
315pub struct DebugMap<'a, 'b: 'a> {
316 fmt: &'a mut fmt::Formatter<'b>,
317 result: fmt::Result,
318 has_fields: bool,
319}
320
321pub 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
330impl<'a, 'b: 'a> DebugMap<'a, 'b> {
331 /// Adds a new entry to the map output.
62682a34
SL
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> {
c34b1796
AL
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
62682a34
SL
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 {
c34b1796
AL
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}