]> git.proxmox.com Git - rustc.git/blame - src/libcore/fmt/builders.rs
Imported Upstream version 1.9.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
e9174d1e 11use prelude::v1::*;
c34b1796
AL
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 {
54a0048b 32 self.fmt.write_str(" ")?;
c34b1796
AL
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 };
54a0048b 45 self.fmt.write_str(&s[..split])?;
c34b1796
AL
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]
54a0048b 57#[allow(missing_debug_implementations)]
62682a34 58#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
59pub struct DebugStruct<'a, 'b: 'a> {
60 fmt: &'a mut fmt::Formatter<'b>,
61 result: fmt::Result,
62 has_fields: bool,
63}
64
b039eaaf
SL
65pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
66 name: &str)
c34b1796
AL
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
76impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
77 /// Adds a new field to the generated struct output.
62682a34
SL
78 #[stable(feature = "debug_builders", since = "1.2.0")]
79 pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
c34b1796
AL
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);
b039eaaf
SL
89 fmt::write(&mut writer,
90 format_args!("{}\n{}: {:#?}", prefix, name, value))
c34b1796
AL
91 } else {
92 write!(self.fmt, "{} {}: {:?}", prefix, name, value)
93 }
94 });
95
96 self.has_fields = true;
97 self
98 }
99
62682a34
SL
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 {
c34b1796
AL
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]
54a0048b 124#[allow(missing_debug_implementations)]
62682a34 125#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
126pub struct DebugTuple<'a, 'b: 'a> {
127 fmt: &'a mut fmt::Formatter<'b>,
128 result: fmt::Result,
54a0048b
SL
129 fields: usize,
130 empty_name: bool,
c34b1796
AL
131}
132
133pub 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,
54a0048b
SL
138 fields: 0,
139 empty_name: name.is_empty(),
c34b1796
AL
140 }
141}
142
143impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
144 /// Adds a new field to the generated tuple struct output.
62682a34
SL
145 #[stable(feature = "debug_builders", since = "1.2.0")]
146 pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
c34b1796 147 self.result = self.result.and_then(|_| {
54a0048b 148 let (prefix, space) = if self.fields > 0 {
c34b1796
AL
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
54a0048b 162 self.fields += 1;
c34b1796
AL
163 self
164 }
165
62682a34
SL
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 {
54a0048b 169 if self.fields > 0 {
c34b1796
AL
170 self.result = self.result.and_then(|_| {
171 if self.is_pretty() {
54a0048b
SL
172 self.fmt.write_str("\n")?;
173 }
174 if self.fields == 1 && self.empty_name {
175 self.fmt.write_str(",")?;
c34b1796 176 }
54a0048b 177 self.fmt.write_str(")")
c34b1796
AL
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
188struct DebugInner<'a, 'b: 'a> {
189 fmt: &'a mut fmt::Formatter<'b>,
190 result: fmt::Result,
191 has_fields: bool,
192}
193
194impl<'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);
b039eaaf
SL
199 let prefix = if self.has_fields {
200 ","
201 } else {
202 ""
203 };
c34b1796
AL
204 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
205 } else {
b039eaaf
SL
206 let prefix = if self.has_fields {
207 ", "
208 } else {
209 ""
210 };
c34b1796
AL
211 write!(self.fmt, "{}{:?}", prefix, entry)
212 }
213 });
214
215 self.has_fields = true;
216 }
217
218 pub fn finish(&mut self) {
b039eaaf
SL
219 let prefix = if self.is_pretty() && self.has_fields {
220 "\n"
221 } else {
222 ""
223 };
c34b1796
AL
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]
54a0048b 236#[allow(missing_debug_implementations)]
62682a34 237#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
238pub struct DebugSet<'a, 'b: 'a> {
239 inner: DebugInner<'a, 'b>,
240}
241
242pub 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,
b039eaaf 249 },
c34b1796
AL
250 }
251}
252
253impl<'a, 'b: 'a> DebugSet<'a, 'b> {
254 /// Adds a new entry to the set output.
62682a34
SL
255 #[stable(feature = "debug_builders", since = "1.2.0")]
256 pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
c34b1796
AL
257 self.inner.entry(entry);
258 self
259 }
260
62682a34
SL
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>
b039eaaf
SL
264 where D: fmt::Debug,
265 I: IntoIterator<Item = D>
266 {
62682a34
SL
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 {
c34b1796
AL
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]
54a0048b 285#[allow(missing_debug_implementations)]
62682a34 286#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
287pub struct DebugList<'a, 'b: 'a> {
288 inner: DebugInner<'a, 'b>,
289}
290
291pub 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,
b039eaaf 298 },
c34b1796
AL
299 }
300}
301
302impl<'a, 'b: 'a> DebugList<'a, 'b> {
62682a34
SL
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> {
c34b1796
AL
306 self.inner.entry(entry);
307 self
308 }
309
62682a34
SL
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>
b039eaaf
SL
313 where D: fmt::Debug,
314 I: IntoIterator<Item = D>
315 {
62682a34
SL
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 {
c34b1796
AL
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]
54a0048b 334#[allow(missing_debug_implementations)]
62682a34 335#[stable(feature = "debug_builders", since = "1.2.0")]
c34b1796
AL
336pub struct DebugMap<'a, 'b: 'a> {
337 fmt: &'a mut fmt::Formatter<'b>,
338 result: fmt::Result,
339 has_fields: bool,
340}
341
342pub 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
351impl<'a, 'b: 'a> DebugMap<'a, 'b> {
352 /// Adds a new entry to the map output.
62682a34
SL
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> {
c34b1796
AL
355 self.result = self.result.and_then(|_| {
356 if self.is_pretty() {
357 let mut writer = PadAdapter::new(self.fmt);
b039eaaf
SL
358 let prefix = if self.has_fields {
359 ","
360 } else {
361 ""
362 };
363 fmt::write(&mut writer,
364 format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
c34b1796 365 } else {
b039eaaf
SL
366 let prefix = if self.has_fields {
367 ", "
368 } else {
369 ""
370 };
c34b1796
AL
371 write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
372 }
373 });
374
375 self.has_fields = true;
376 self
377 }
378
62682a34
SL
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>
b039eaaf
SL
382 where K: fmt::Debug,
383 V: fmt::Debug,
384 I: IntoIterator<Item = (K, V)>
385 {
62682a34
SL
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 {
b039eaaf
SL
395 let prefix = if self.is_pretty() && self.has_fields {
396 "\n"
397 } else {
398 ""
399 };
c34b1796
AL
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}