1 #![allow(unused_imports)]
2
3 use crate::fmt::{self, Debug, Formatter};
4
5 struct PadAdapter<'buf, 'state> {
6 buf: &'buf mut (dyn fmt::Write + 'buf),
7 state: &'state mut PadAdapterState,
8 }
9
10 struct PadAdapterState {
11 on_newline: bool,
12 }
13
14 impl Default for PadAdapterState {
default() -> Self15 fn default() -> Self {
16 PadAdapterState { on_newline: true }
17 }
18 }
19
20 impl<'buf, 'state> PadAdapter<'buf, 'state> {
wrap<'slot, 'fmt: 'buf + 'slot>( fmt: &'fmt mut fmt::Formatter<'_>, slot: &'slot mut Option<Self>, state: &'state mut PadAdapterState, ) -> fmt::Formatter<'slot>21 fn wrap<'slot, 'fmt: 'buf + 'slot>(
22 fmt: &'fmt mut fmt::Formatter<'_>,
23 slot: &'slot mut Option<Self>,
24 state: &'state mut PadAdapterState,
25 ) -> fmt::Formatter<'slot> {
26 fmt.wrap_buf(move |buf| slot.insert(PadAdapter { buf, state }))
27 }
28 }
29
30 impl fmt::Write for PadAdapter<'_, '_> {
write_str(&mut self, s: &str) -> fmt::Result31 fn write_str(&mut self, s: &str) -> fmt::Result {
32 for s in s.split_inclusive('\n') {
33 if self.state.on_newline {
34 self.buf.write_str(" ")?;
35 }
36
37 self.state.on_newline = s.ends_with('\n');
38 self.buf.write_str(s)?;
39 }
40
41 Ok(())
42 }
43 }
44
45 /// A struct to help with [`fmt::Debug`](Debug) implementations.
46 ///
47 /// This is useful when you wish to output a formatted struct as a part of your
48 /// [`Debug::fmt`] implementation.
49 ///
50 /// This can be constructed by the [`Formatter::debug_struct`] method.
51 ///
52 /// # Examples
53 ///
54 /// ```
55 /// use std::fmt;
56 ///
57 /// struct Foo {
58 /// bar: i32,
59 /// baz: String,
60 /// }
61 ///
62 /// impl fmt::Debug for Foo {
63 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
64 /// fmt.debug_struct("Foo")
65 /// .field("bar", &self.bar)
66 /// .field("baz", &self.baz)
67 /// .finish()
68 /// }
69 /// }
70 ///
71 /// assert_eq!(
72 /// format!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }),
73 /// "Foo { bar: 10, baz: \"Hello World\" }",
74 /// );
75 /// ```
76 #[must_use = "must eventually call `finish()` on Debug builders"]
77 #[allow(missing_debug_implementations)]
78 #[stable(feature = "debug_builders", since = "1.2.0")]
79 pub struct DebugStruct<'a, 'b: 'a> {
80 fmt: &'a mut fmt::Formatter<'b>,
81 result: fmt::Result,
82 has_fields: bool,
83 }
84
debug_struct_new<'a, 'b>( fmt: &'a mut fmt::Formatter<'b>, name: &str, ) -> DebugStruct<'a, 'b>85 pub(super) fn debug_struct_new<'a, 'b>(
86 fmt: &'a mut fmt::Formatter<'b>,
87 name: &str,
88 ) -> DebugStruct<'a, 'b> {
89 let result = fmt.write_str(name);
90 DebugStruct { fmt, result, has_fields: false }
91 }
92
93 impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
94 /// Adds a new field to the generated struct output.
95 ///
96 /// # Examples
97 ///
98 /// ```
99 /// use std::fmt;
100 ///
101 /// struct Bar {
102 /// bar: i32,
103 /// another: String,
104 /// }
105 ///
106 /// impl fmt::Debug for Bar {
107 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
108 /// fmt.debug_struct("Bar")
109 /// .field("bar", &self.bar) // We add `bar` field.
110 /// .field("another", &self.another) // We add `another` field.
111 /// // We even add a field which doesn't exist (because why not?).
112 /// .field("nonexistent_field", &1)
113 /// .finish() // We're good to go!
114 /// }
115 /// }
116 ///
117 /// assert_eq!(
118 /// format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
119 /// "Bar { bar: 10, another: \"Hello World\", nonexistent_field: 1 }",
120 /// );
121 /// ```
122 #[stable(feature = "debug_builders", since = "1.2.0")]
field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self123 pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self {
124 self.result = self.result.and_then(|_| {
125 if self.is_pretty() {
126 if !self.has_fields {
127 self.fmt.write_str(" {\n")?;
128 }
129 let mut slot = None;
130 let mut state = Default::default();
131 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
132 writer.write_str(name)?;
133 writer.write_str(": ")?;
134 value.fmt(&mut writer)?;
135 writer.write_str(",\n")
136 } else {
137 let prefix = if self.has_fields { ", " } else { " { " };
138 self.fmt.write_str(prefix)?;
139 self.fmt.write_str(name)?;
140 self.fmt.write_str(": ")?;
141 value.fmt(self.fmt)
142 }
143 });
144
145 self.has_fields = true;
146 self
147 }
148
149 /// Marks the struct as non-exhaustive, indicating to the reader that there are some other
150 /// fields that are not shown in the debug representation.
151 ///
152 /// # Examples
153 ///
154 /// ```
155 /// use std::fmt;
156 ///
157 /// struct Bar {
158 /// bar: i32,
159 /// hidden: f32,
160 /// }
161 ///
162 /// impl fmt::Debug for Bar {
163 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
164 /// fmt.debug_struct("Bar")
165 /// .field("bar", &self.bar)
166 /// .finish_non_exhaustive() // Show that some other field(s) exist.
167 /// }
168 /// }
169 ///
170 /// assert_eq!(
171 /// format!("{:?}", Bar { bar: 10, hidden: 1.0 }),
172 /// "Bar { bar: 10, .. }",
173 /// );
174 /// ```
175 #[stable(feature = "debug_non_exhaustive", since = "1.53.0")]
finish_non_exhaustive(&mut self) -> fmt::Result176 pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
177 self.result = self.result.and_then(|_| {
178 if self.has_fields {
179 if self.is_pretty() {
180 let mut slot = None;
181 let mut state = Default::default();
182 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
183 writer.write_str("..\n")?;
184 self.fmt.write_str("}")
185 } else {
186 self.fmt.write_str(", .. }")
187 }
188 } else {
189 self.fmt.write_str(" { .. }")
190 }
191 });
192 self.result
193 }
194
195 /// Finishes output and returns any error encountered.
196 ///
197 /// # Examples
198 ///
199 /// ```
200 /// use std::fmt;
201 ///
202 /// struct Bar {
203 /// bar: i32,
204 /// baz: String,
205 /// }
206 ///
207 /// impl fmt::Debug for Bar {
208 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
209 /// fmt.debug_struct("Bar")
210 /// .field("bar", &self.bar)
211 /// .field("baz", &self.baz)
212 /// .finish() // You need to call it to "finish" the
213 /// // struct formatting.
214 /// }
215 /// }
216 ///
217 /// assert_eq!(
218 /// format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }),
219 /// "Bar { bar: 10, baz: \"Hello World\" }",
220 /// );
221 /// ```
222 #[stable(feature = "debug_builders", since = "1.2.0")]
finish(&mut self) -> fmt::Result223 pub fn finish(&mut self) -> fmt::Result {
224 if self.has_fields {
225 self.result = self.result.and_then(|_| {
226 if self.is_pretty() { self.fmt.write_str("}") } else { self.fmt.write_str(" }") }
227 });
228 }
229 self.result
230 }
231
is_pretty(&self) -> bool232 fn is_pretty(&self) -> bool {
233 self.fmt.alternate()
234 }
235 }
236
237 /// A struct to help with [`fmt::Debug`](Debug) implementations.
238 ///
239 /// This is useful when you wish to output a formatted tuple as a part of your
240 /// [`Debug::fmt`] implementation.
241 ///
242 /// This can be constructed by the [`Formatter::debug_tuple`] method.
243 ///
244 /// # Examples
245 ///
246 /// ```
247 /// use std::fmt;
248 ///
249 /// struct Foo(i32, String);
250 ///
251 /// impl fmt::Debug for Foo {
252 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
253 /// fmt.debug_tuple("Foo")
254 /// .field(&self.0)
255 /// .field(&self.1)
256 /// .finish()
257 /// }
258 /// }
259 ///
260 /// assert_eq!(
261 /// format!("{:?}", Foo(10, "Hello World".to_string())),
262 /// "Foo(10, \"Hello World\")",
263 /// );
264 /// ```
265 #[must_use = "must eventually call `finish()` on Debug builders"]
266 #[allow(missing_debug_implementations)]
267 #[stable(feature = "debug_builders", since = "1.2.0")]
268 pub struct DebugTuple<'a, 'b: 'a> {
269 fmt: &'a mut fmt::Formatter<'b>,
270 result: fmt::Result,
271 fields: usize,
272 empty_name: bool,
273 }
274
debug_tuple_new<'a, 'b>( fmt: &'a mut fmt::Formatter<'b>, name: &str, ) -> DebugTuple<'a, 'b>275 pub(super) fn debug_tuple_new<'a, 'b>(
276 fmt: &'a mut fmt::Formatter<'b>,
277 name: &str,
278 ) -> DebugTuple<'a, 'b> {
279 let result = fmt.write_str(name);
280 DebugTuple { fmt, result, fields: 0, empty_name: name.is_empty() }
281 }
282
283 impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
284 /// Adds a new field to the generated tuple struct output.
285 ///
286 /// # Examples
287 ///
288 /// ```
289 /// use std::fmt;
290 ///
291 /// struct Foo(i32, String);
292 ///
293 /// impl fmt::Debug for Foo {
294 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
295 /// fmt.debug_tuple("Foo")
296 /// .field(&self.0) // We add the first field.
297 /// .field(&self.1) // We add the second field.
298 /// .finish() // We're good to go!
299 /// }
300 /// }
301 ///
302 /// assert_eq!(
303 /// format!("{:?}", Foo(10, "Hello World".to_string())),
304 /// "Foo(10, \"Hello World\")",
305 /// );
306 /// ```
307 #[stable(feature = "debug_builders", since = "1.2.0")]
field(&mut self, value: &dyn fmt::Debug) -> &mut Self308 pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self {
309 self.result = self.result.and_then(|_| {
310 if self.is_pretty() {
311 if self.fields == 0 {
312 self.fmt.write_str("(\n")?;
313 }
314 let mut slot = None;
315 let mut state = Default::default();
316 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
317 value.fmt(&mut writer)?;
318 writer.write_str(",\n")
319 } else {
320 let prefix = if self.fields == 0 { "(" } else { ", " };
321 self.fmt.write_str(prefix)?;
322 value.fmt(self.fmt)
323 }
324 });
325
326 self.fields += 1;
327 self
328 }
329
330 /// Finishes output and returns any error encountered.
331 ///
332 /// # Examples
333 ///
334 /// ```
335 /// use std::fmt;
336 ///
337 /// struct Foo(i32, String);
338 ///
339 /// impl fmt::Debug for Foo {
340 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
341 /// fmt.debug_tuple("Foo")
342 /// .field(&self.0)
343 /// .field(&self.1)
344 /// .finish() // You need to call it to "finish" the
345 /// // tuple formatting.
346 /// }
347 /// }
348 ///
349 /// assert_eq!(
350 /// format!("{:?}", Foo(10, "Hello World".to_string())),
351 /// "Foo(10, \"Hello World\")",
352 /// );
353 /// ```
354 #[stable(feature = "debug_builders", since = "1.2.0")]
finish(&mut self) -> fmt::Result355 pub fn finish(&mut self) -> fmt::Result {
356 if self.fields > 0 {
357 self.result = self.result.and_then(|_| {
358 if self.fields == 1 && self.empty_name && !self.is_pretty() {
359 self.fmt.write_str(",")?;
360 }
361 self.fmt.write_str(")")
362 });
363 }
364 self.result
365 }
366
is_pretty(&self) -> bool367 fn is_pretty(&self) -> bool {
368 self.fmt.alternate()
369 }
370 }
371
372 struct DebugInner<'a, 'b: 'a> {
373 fmt: &'a mut fmt::Formatter<'b>,
374 result: fmt::Result,
375 has_fields: bool,
376 }
377
378 impl<'a, 'b: 'a> DebugInner<'a, 'b> {
entry(&mut self, entry: &dyn fmt::Debug)379 fn entry(&mut self, entry: &dyn fmt::Debug) {
380 self.result = self.result.and_then(|_| {
381 if self.is_pretty() {
382 if !self.has_fields {
383 self.fmt.write_str("\n")?;
384 }
385 let mut slot = None;
386 let mut state = Default::default();
387 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
388 entry.fmt(&mut writer)?;
389 writer.write_str(",\n")
390 } else {
391 if self.has_fields {
392 self.fmt.write_str(", ")?
393 }
394 entry.fmt(self.fmt)
395 }
396 });
397
398 self.has_fields = true;
399 }
400
is_pretty(&self) -> bool401 fn is_pretty(&self) -> bool {
402 self.fmt.alternate()
403 }
404 }
405
406 /// A struct to help with [`fmt::Debug`](Debug) implementations.
407 ///
408 /// This is useful when you wish to output a formatted set of items as a part
409 /// of your [`Debug::fmt`] implementation.
410 ///
411 /// This can be constructed by the [`Formatter::debug_set`] method.
412 ///
413 /// # Examples
414 ///
415 /// ```
416 /// use std::fmt;
417 ///
418 /// struct Foo(Vec<i32>);
419 ///
420 /// impl fmt::Debug for Foo {
421 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
422 /// fmt.debug_set().entries(self.0.iter()).finish()
423 /// }
424 /// }
425 ///
426 /// assert_eq!(
427 /// format!("{:?}", Foo(vec![10, 11])),
428 /// "{10, 11}",
429 /// );
430 /// ```
431 #[must_use = "must eventually call `finish()` on Debug builders"]
432 #[allow(missing_debug_implementations)]
433 #[stable(feature = "debug_builders", since = "1.2.0")]
434 pub struct DebugSet<'a, 'b: 'a> {
435 inner: DebugInner<'a, 'b>,
436 }
437
debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b>438 pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
439 let result = fmt.write_str("{");
440 DebugSet { inner: DebugInner { fmt, result, has_fields: false } }
441 }
442
443 impl<'a, 'b: 'a> DebugSet<'a, 'b> {
444 /// Adds a new entry to the set output.
445 ///
446 /// # Examples
447 ///
448 /// ```
449 /// use std::fmt;
450 ///
451 /// struct Foo(Vec<i32>, Vec<u32>);
452 ///
453 /// impl fmt::Debug for Foo {
454 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
455 /// fmt.debug_set()
456 /// .entry(&self.0) // Adds the first "entry".
457 /// .entry(&self.1) // Adds the second "entry".
458 /// .finish()
459 /// }
460 /// }
461 ///
462 /// assert_eq!(
463 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
464 /// "{[10, 11], [12, 13]}",
465 /// );
466 /// ```
467 #[stable(feature = "debug_builders", since = "1.2.0")]
entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self468 pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
469 self.inner.entry(entry);
470 self
471 }
472
473 /// Adds the contents of an iterator of entries to the set output.
474 ///
475 /// # Examples
476 ///
477 /// ```
478 /// use std::fmt;
479 ///
480 /// struct Foo(Vec<i32>, Vec<u32>);
481 ///
482 /// impl fmt::Debug for Foo {
483 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
484 /// fmt.debug_set()
485 /// .entries(self.0.iter()) // Adds the first "entry".
486 /// .entries(self.1.iter()) // Adds the second "entry".
487 /// .finish()
488 /// }
489 /// }
490 ///
491 /// assert_eq!(
492 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
493 /// "{10, 11, 12, 13}",
494 /// );
495 /// ```
496 #[stable(feature = "debug_builders", since = "1.2.0")]
entries<D, I>(&mut self, entries: I) -> &mut Self where D: fmt::Debug, I: IntoIterator<Item = D>,497 pub fn entries<D, I>(&mut self, entries: I) -> &mut Self
498 where
499 D: fmt::Debug,
500 I: IntoIterator<Item = D>,
501 {
502 for entry in entries {
503 self.entry(&entry);
504 }
505 self
506 }
507
508 /// Finishes output and returns any error encountered.
509 ///
510 /// # Examples
511 ///
512 /// ```
513 /// use std::fmt;
514 ///
515 /// struct Foo(Vec<i32>);
516 ///
517 /// impl fmt::Debug for Foo {
518 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
519 /// fmt.debug_set()
520 /// .entries(self.0.iter())
521 /// .finish() // Ends the struct formatting.
522 /// }
523 /// }
524 ///
525 /// assert_eq!(
526 /// format!("{:?}", Foo(vec![10, 11])),
527 /// "{10, 11}",
528 /// );
529 /// ```
530 #[stable(feature = "debug_builders", since = "1.2.0")]
finish(&mut self) -> fmt::Result531 pub fn finish(&mut self) -> fmt::Result {
532 self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
533 }
534 }
535
536 /// A struct to help with [`fmt::Debug`](Debug) implementations.
537 ///
538 /// This is useful when you wish to output a formatted list of items as a part
539 /// of your [`Debug::fmt`] implementation.
540 ///
541 /// This can be constructed by the [`Formatter::debug_list`] method.
542 ///
543 /// # Examples
544 ///
545 /// ```
546 /// use std::fmt;
547 ///
548 /// struct Foo(Vec<i32>);
549 ///
550 /// impl fmt::Debug for Foo {
551 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
552 /// fmt.debug_list().entries(self.0.iter()).finish()
553 /// }
554 /// }
555 ///
556 /// assert_eq!(
557 /// format!("{:?}", Foo(vec![10, 11])),
558 /// "[10, 11]",
559 /// );
560 /// ```
561 #[must_use = "must eventually call `finish()` on Debug builders"]
562 #[allow(missing_debug_implementations)]
563 #[stable(feature = "debug_builders", since = "1.2.0")]
564 pub struct DebugList<'a, 'b: 'a> {
565 inner: DebugInner<'a, 'b>,
566 }
567
debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b>568 pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
569 let result = fmt.write_str("[");
570 DebugList { inner: DebugInner { fmt, result, has_fields: false } }
571 }
572
573 impl<'a, 'b: 'a> DebugList<'a, 'b> {
574 /// Adds a new entry to the list output.
575 ///
576 /// # Examples
577 ///
578 /// ```
579 /// use std::fmt;
580 ///
581 /// struct Foo(Vec<i32>, Vec<u32>);
582 ///
583 /// impl fmt::Debug for Foo {
584 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
585 /// fmt.debug_list()
586 /// .entry(&self.0) // We add the first "entry".
587 /// .entry(&self.1) // We add the second "entry".
588 /// .finish()
589 /// }
590 /// }
591 ///
592 /// assert_eq!(
593 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
594 /// "[[10, 11], [12, 13]]",
595 /// );
596 /// ```
597 #[stable(feature = "debug_builders", since = "1.2.0")]
entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self598 pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
599 self.inner.entry(entry);
600 self
601 }
602
603 /// Adds the contents of an iterator of entries to the list output.
604 ///
605 /// # Examples
606 ///
607 /// ```
608 /// use std::fmt;
609 ///
610 /// struct Foo(Vec<i32>, Vec<u32>);
611 ///
612 /// impl fmt::Debug for Foo {
613 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
614 /// fmt.debug_list()
615 /// .entries(self.0.iter())
616 /// .entries(self.1.iter())
617 /// .finish()
618 /// }
619 /// }
620 ///
621 /// assert_eq!(
622 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
623 /// "[10, 11, 12, 13]",
624 /// );
625 /// ```
626 #[stable(feature = "debug_builders", since = "1.2.0")]
entries<D, I>(&mut self, entries: I) -> &mut Self where D: fmt::Debug, I: IntoIterator<Item = D>,627 pub fn entries<D, I>(&mut self, entries: I) -> &mut Self
628 where
629 D: fmt::Debug,
630 I: IntoIterator<Item = D>,
631 {
632 for entry in entries {
633 self.entry(&entry);
634 }
635 self
636 }
637
638 /// Finishes output and returns any error encountered.
639 ///
640 /// # Examples
641 ///
642 /// ```
643 /// use std::fmt;
644 ///
645 /// struct Foo(Vec<i32>);
646 ///
647 /// impl fmt::Debug for Foo {
648 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
649 /// fmt.debug_list()
650 /// .entries(self.0.iter())
651 /// .finish() // Ends the struct formatting.
652 /// }
653 /// }
654 ///
655 /// assert_eq!(
656 /// format!("{:?}", Foo(vec![10, 11])),
657 /// "[10, 11]",
658 /// );
659 /// ```
660 #[stable(feature = "debug_builders", since = "1.2.0")]
finish(&mut self) -> fmt::Result661 pub fn finish(&mut self) -> fmt::Result {
662 self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
663 }
664 }
665
666 /// A struct to help with [`fmt::Debug`](Debug) implementations.
667 ///
668 /// This is useful when you wish to output a formatted map as a part of your
669 /// [`Debug::fmt`] implementation.
670 ///
671 /// This can be constructed by the [`Formatter::debug_map`] method.
672 ///
673 /// # Examples
674 ///
675 /// ```
676 /// use std::fmt;
677 ///
678 /// struct Foo(Vec<(String, i32)>);
679 ///
680 /// impl fmt::Debug for Foo {
681 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
682 /// fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish()
683 /// }
684 /// }
685 ///
686 /// assert_eq!(
687 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
688 /// "{\"A\": 10, \"B\": 11}",
689 /// );
690 /// ```
691 #[must_use = "must eventually call `finish()` on Debug builders"]
692 #[allow(missing_debug_implementations)]
693 #[stable(feature = "debug_builders", since = "1.2.0")]
694 pub struct DebugMap<'a, 'b: 'a> {
695 fmt: &'a mut fmt::Formatter<'b>,
696 result: fmt::Result,
697 has_fields: bool,
698 has_key: bool,
699 // The state of newlines is tracked between keys and values
700 state: PadAdapterState,
701 }
702
debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b>703 pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
704 let result = fmt.write_str("{");
705 DebugMap { fmt, result, has_fields: false, has_key: false, state: Default::default() }
706 }
707
708 impl<'a, 'b: 'a> DebugMap<'a, 'b> {
709 /// Adds a new entry to the map output.
710 ///
711 /// # Examples
712 ///
713 /// ```
714 /// use std::fmt;
715 ///
716 /// struct Foo(Vec<(String, i32)>);
717 ///
718 /// impl fmt::Debug for Foo {
719 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
720 /// fmt.debug_map()
721 /// .entry(&"whole", &self.0) // We add the "whole" entry.
722 /// .finish()
723 /// }
724 /// }
725 ///
726 /// assert_eq!(
727 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
728 /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
729 /// );
730 /// ```
731 #[stable(feature = "debug_builders", since = "1.2.0")]
entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut Self732 pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut Self {
733 self.key(key).value(value)
734 }
735
736 /// Adds the key part of a new entry to the map output.
737 ///
738 /// This method, together with `value`, is an alternative to `entry` that
739 /// can be used when the complete entry isn't known upfront. Prefer the `entry`
740 /// method when it's possible to use.
741 ///
742 /// # Panics
743 ///
744 /// `key` must be called before `value` and each call to `key` must be followed
745 /// by a corresponding call to `value`. Otherwise this method will panic.
746 ///
747 /// # Examples
748 ///
749 /// ```
750 /// use std::fmt;
751 ///
752 /// struct Foo(Vec<(String, i32)>);
753 ///
754 /// impl fmt::Debug for Foo {
755 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
756 /// fmt.debug_map()
757 /// .key(&"whole").value(&self.0) // We add the "whole" entry.
758 /// .finish()
759 /// }
760 /// }
761 ///
762 /// assert_eq!(
763 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
764 /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
765 /// );
766 /// ```
767 #[stable(feature = "debug_map_key_value", since = "1.42.0")]
key(&mut self, key: &dyn fmt::Debug) -> &mut Self768 pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self {
769 self.result = self.result.and_then(|_| {
770 assert!(
771 !self.has_key,
772 "attempted to begin a new map entry \
773 without completing the previous one"
774 );
775
776 if self.is_pretty() {
777 if !self.has_fields {
778 self.fmt.write_str("\n")?;
779 }
780 let mut slot = None;
781 self.state = Default::default();
782 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
783 key.fmt(&mut writer)?;
784 writer.write_str(": ")?;
785 } else {
786 if self.has_fields {
787 self.fmt.write_str(", ")?
788 }
789 key.fmt(self.fmt)?;
790 self.fmt.write_str(": ")?;
791 }
792
793 self.has_key = true;
794 Ok(())
795 });
796
797 self
798 }
799
800 /// Adds the value part of a new entry to the map output.
801 ///
802 /// This method, together with `key`, is an alternative to `entry` that
803 /// can be used when the complete entry isn't known upfront. Prefer the `entry`
804 /// method when it's possible to use.
805 ///
806 /// # Panics
807 ///
808 /// `key` must be called before `value` and each call to `key` must be followed
809 /// by a corresponding call to `value`. Otherwise this method will panic.
810 ///
811 /// # Examples
812 ///
813 /// ```
814 /// use std::fmt;
815 ///
816 /// struct Foo(Vec<(String, i32)>);
817 ///
818 /// impl fmt::Debug for Foo {
819 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
820 /// fmt.debug_map()
821 /// .key(&"whole").value(&self.0) // We add the "whole" entry.
822 /// .finish()
823 /// }
824 /// }
825 ///
826 /// assert_eq!(
827 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
828 /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
829 /// );
830 /// ```
831 #[stable(feature = "debug_map_key_value", since = "1.42.0")]
value(&mut self, value: &dyn fmt::Debug) -> &mut Self832 pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self {
833 self.result = self.result.and_then(|_| {
834 assert!(self.has_key, "attempted to format a map value before its key");
835
836 if self.is_pretty() {
837 let mut slot = None;
838 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
839 value.fmt(&mut writer)?;
840 writer.write_str(",\n")?;
841 } else {
842 value.fmt(self.fmt)?;
843 }
844
845 self.has_key = false;
846 Ok(())
847 });
848
849 self.has_fields = true;
850 self
851 }
852
853 /// Adds the contents of an iterator of entries to the map output.
854 ///
855 /// # Examples
856 ///
857 /// ```
858 /// use std::fmt;
859 ///
860 /// struct Foo(Vec<(String, i32)>);
861 ///
862 /// impl fmt::Debug for Foo {
863 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
864 /// fmt.debug_map()
865 /// // We map our vec so each entries' first field will become
866 /// // the "key".
867 /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
868 /// .finish()
869 /// }
870 /// }
871 ///
872 /// assert_eq!(
873 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
874 /// "{\"A\": 10, \"B\": 11}",
875 /// );
876 /// ```
877 #[stable(feature = "debug_builders", since = "1.2.0")]
entries<K, V, I>(&mut self, entries: I) -> &mut Self where K: fmt::Debug, V: fmt::Debug, I: IntoIterator<Item = (K, V)>,878 pub fn entries<K, V, I>(&mut self, entries: I) -> &mut Self
879 where
880 K: fmt::Debug,
881 V: fmt::Debug,
882 I: IntoIterator<Item = (K, V)>,
883 {
884 for (k, v) in entries {
885 self.entry(&k, &v);
886 }
887 self
888 }
889
890 /// Finishes output and returns any error encountered.
891 ///
892 /// # Panics
893 ///
894 /// `key` must be called before `value` and each call to `key` must be followed
895 /// by a corresponding call to `value`. Otherwise this method will panic.
896 ///
897 /// # Examples
898 ///
899 /// ```
900 /// use std::fmt;
901 ///
902 /// struct Foo(Vec<(String, i32)>);
903 ///
904 /// impl fmt::Debug for Foo {
905 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
906 /// fmt.debug_map()
907 /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
908 /// .finish() // Ends the struct formatting.
909 /// }
910 /// }
911 ///
912 /// assert_eq!(
913 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
914 /// "{\"A\": 10, \"B\": 11}",
915 /// );
916 /// ```
917 #[stable(feature = "debug_builders", since = "1.2.0")]
finish(&mut self) -> fmt::Result918 pub fn finish(&mut self) -> fmt::Result {
919 self.result.and_then(|_| {
920 assert!(!self.has_key, "attempted to finish a map with a partial entry");
921
922 self.fmt.write_str("}")
923 })
924 }
925
is_pretty(&self) -> bool926 fn is_pretty(&self) -> bool {
927 self.fmt.alternate()
928 }
929 }
930