]> git.proxmox.com Git - rustc.git/blob - src/libcore/fmt/builders.rs
New upstream version 1.13.0+dfsg1
[rustc.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 }