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