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