]> git.proxmox.com Git - rustc.git/blob - src/libcore/fmt/builders.rs
Merge tag 'upstream/1.0.0_beta'
[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 pub struct DebugStruct<'a, 'b: 'a> {
58 fmt: &'a mut fmt::Formatter<'b>,
59 result: fmt::Result,
60 has_fields: bool,
61 }
62
63 pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str)
64 -> DebugStruct<'a, 'b> {
65 let result = fmt.write_str(name);
66 DebugStruct {
67 fmt: fmt,
68 result: result,
69 has_fields: false,
70 }
71 }
72
73 impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
74 /// Adds a new field to the generated struct output.
75 #[unstable(feature = "debug_builders", reason = "method was just created")]
76 pub fn field(mut self, name: &str, value: &fmt::Debug) -> DebugStruct<'a, 'b> {
77 self.result = self.result.and_then(|_| {
78 let prefix = if self.has_fields {
79 ","
80 } else {
81 " {"
82 };
83
84 if self.is_pretty() {
85 let mut writer = PadAdapter::new(self.fmt);
86 fmt::write(&mut writer, format_args!("{}\n{}: {:#?}", prefix, name, value))
87 } else {
88 write!(self.fmt, "{} {}: {:?}", prefix, name, value)
89 }
90 });
91
92 self.has_fields = true;
93 self
94 }
95
96 /// Consumes the `DebugStruct`, finishing output and returning any error
97 /// encountered.
98 #[unstable(feature = "debug_builders", reason = "method was just created")]
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 pub struct DebugTuple<'a, 'b: 'a> {
122 fmt: &'a mut fmt::Formatter<'b>,
123 result: fmt::Result,
124 has_fields: bool,
125 }
126
127 pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
128 let result = fmt.write_str(name);
129 DebugTuple {
130 fmt: fmt,
131 result: result,
132 has_fields: false,
133 }
134 }
135
136 impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
137 /// Adds a new field to the generated tuple struct output.
138 #[unstable(feature = "debug_builders", reason = "method was just created")]
139 pub fn field(mut self, value: &fmt::Debug) -> DebugTuple<'a, 'b> {
140 self.result = self.result.and_then(|_| {
141 let (prefix, space) = if self.has_fields {
142 (",", " ")
143 } else {
144 ("(", "")
145 };
146
147 if self.is_pretty() {
148 let mut writer = PadAdapter::new(self.fmt);
149 fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
150 } else {
151 write!(self.fmt, "{}{}{:?}", prefix, space, value)
152 }
153 });
154
155 self.has_fields = true;
156 self
157 }
158
159 /// Consumes the `DebugTuple`, finishing output and returning any error
160 /// encountered.
161 #[unstable(feature = "debug_builders", reason = "method was just created")]
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 pub struct DebugSet<'a, 'b: 'a> {
217 inner: DebugInner<'a, 'b>,
218 }
219
220 pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
221 let result = write!(fmt, "{{");
222 DebugSet {
223 inner: DebugInner {
224 fmt: fmt,
225 result: result,
226 has_fields: false,
227 }
228 }
229 }
230
231 impl<'a, 'b: 'a> DebugSet<'a, 'b> {
232 /// Adds a new entry to the set output.
233 #[unstable(feature = "debug_builders", reason = "method was just created")]
234 pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> {
235 self.inner.entry(entry);
236 self
237 }
238
239 /// Consumes the `DebugSet`, finishing output and returning any error
240 /// encountered.
241 #[unstable(feature = "debug_builders", reason = "method was just created")]
242 pub fn finish(mut self) -> fmt::Result {
243 self.inner.finish();
244 self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
245 }
246 }
247
248 /// A struct to help with `fmt::Debug` implementations.
249 ///
250 /// Constructed by the `Formatter::debug_list` method.
251 #[must_use]
252 pub struct DebugList<'a, 'b: 'a> {
253 inner: DebugInner<'a, 'b>,
254 }
255
256 pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
257 let result = write!(fmt, "[");
258 DebugList {
259 inner: DebugInner {
260 fmt: fmt,
261 result: result,
262 has_fields: false,
263 }
264 }
265 }
266
267 impl<'a, 'b: 'a> DebugList<'a, 'b> {
268 /// Adds a new entry to the set output.
269 #[unstable(feature = "debug_builders", reason = "method was just created")]
270 pub fn entry(mut self, entry: &fmt::Debug) -> DebugList<'a, 'b> {
271 self.inner.entry(entry);
272 self
273 }
274
275 /// Consumes the `DebugSet`, finishing output and returning any error
276 /// encountered.
277 #[unstable(feature = "debug_builders", reason = "method was just created")]
278 pub fn finish(mut self) -> fmt::Result {
279 self.inner.finish();
280 self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
281 }
282 }
283
284 /// A struct to help with `fmt::Debug` implementations.
285 ///
286 /// Constructed by the `Formatter::debug_map` method.
287 #[must_use]
288 pub struct DebugMap<'a, 'b: 'a> {
289 fmt: &'a mut fmt::Formatter<'b>,
290 result: fmt::Result,
291 has_fields: bool,
292 }
293
294 pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
295 let result = write!(fmt, "{{");
296 DebugMap {
297 fmt: fmt,
298 result: result,
299 has_fields: false,
300 }
301 }
302
303 impl<'a, 'b: 'a> DebugMap<'a, 'b> {
304 /// Adds a new entry to the map output.
305 #[unstable(feature = "debug_builders", reason = "method was just created")]
306 pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> {
307 self.result = self.result.and_then(|_| {
308 if self.is_pretty() {
309 let mut writer = PadAdapter::new(self.fmt);
310 let prefix = if self.has_fields { "," } else { "" };
311 fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
312 } else {
313 let prefix = if self.has_fields { ", " } else { "" };
314 write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
315 }
316 });
317
318 self.has_fields = true;
319 self
320 }
321
322 /// Consumes the `DebugMap`, finishing output and returning any error
323 /// encountered.
324 #[unstable(feature = "debug_builders", reason = "method was just created")]
325 pub fn finish(self) -> fmt::Result {
326 let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
327 self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
328 }
329
330 fn is_pretty(&self) -> bool {
331 self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
332 }
333 }