Skip to main content

core/fmt/
builders.rs

1#![allow(unused_imports)]
2
3use crate::cell::Cell;
4use crate::fmt::{self, Debug, Formatter};
5
6struct PadAdapter<'buf, 'state> {
7    buf: &'buf mut (dyn fmt::Write + 'buf),
8    state: &'state mut PadAdapterState,
9}
10
11struct PadAdapterState {
12    on_newline: bool,
13}
14
15impl Default for PadAdapterState {
16    fn default() -> Self {
17        PadAdapterState { on_newline: true }
18    }
19}
20
21impl<'buf, 'state> PadAdapter<'buf, 'state> {
22    fn wrap<'slot, 'fmt: 'buf + 'slot>(
23        fmt: &'fmt mut fmt::Formatter<'_>,
24        slot: &'slot mut Option<Self>,
25        state: &'state mut PadAdapterState,
26    ) -> fmt::Formatter<'slot> {
27        fmt.wrap_buf(move |buf| slot.insert(PadAdapter { buf, state }))
28    }
29}
30
31impl fmt::Write for PadAdapter<'_, '_> {
32    fn write_str(&mut self, s: &str) -> fmt::Result {
33        for s in s.split_inclusive('\n') {
34            if self.state.on_newline {
35                self.buf.write_str("    ")?;
36            }
37
38            self.state.on_newline = s.ends_with('\n');
39            self.buf.write_str(s)?;
40        }
41
42        Ok(())
43    }
44
45    fn write_char(&mut self, c: char) -> fmt::Result {
46        if self.state.on_newline {
47            self.buf.write_str("    ")?;
48        }
49        self.state.on_newline = c == '\n';
50        self.buf.write_char(c)
51    }
52}
53
54/// Wraps an `FnOnce` formatting closure in a type that implements [`fmt::Debug`] by calling the
55/// closure, allowing the `*_with` builder methods to forward to their `&dyn fmt::Debug`
56/// counterparts.
57///
58/// By doing this, the builder logic is monomorphized only once and not for every closure type
59/// (see #149745).
60///
61/// Formatting a `DebugOnce` consumes the closure, so attempting to format it more than once
62/// panics. This never happens because the debug builders format each value exactly once.
63struct DebugOnce<F>(Cell<Option<F>>);
64
65impl<F> fmt::Debug for DebugOnce<F>
66where
67    F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
68{
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        match self.0.take() {
71            Some(value_fmt) => value_fmt(f),
72            None => panic!("formatting closure called more than once"),
73        }
74    }
75}
76
77/// A struct to help with [`fmt::Debug`](Debug) implementations.
78///
79/// This is useful when you wish to output a formatted struct as a part of your
80/// [`Debug::fmt`] implementation.
81///
82/// This can be constructed by the [`Formatter::debug_struct`] method.
83///
84/// # Examples
85///
86/// ```
87/// use std::fmt;
88///
89/// struct Foo {
90///     bar: i32,
91///     baz: String,
92/// }
93///
94/// impl fmt::Debug for Foo {
95///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
96///         fmt.debug_struct("Foo")
97///            .field("bar", &self.bar)
98///            .field("baz", &self.baz)
99///            .finish()
100///     }
101/// }
102///
103/// assert_eq!(
104///     format!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }),
105///     r#"Foo { bar: 10, baz: "Hello World" }"#,
106/// );
107/// ```
108#[must_use = "must eventually call `finish()` on Debug builders"]
109#[allow(missing_debug_implementations)]
110#[stable(feature = "debug_builders", since = "1.2.0")]
111#[rustc_diagnostic_item = "DebugStruct"]
112pub struct DebugStruct<'a, 'b: 'a> {
113    fmt: &'a mut fmt::Formatter<'b>,
114    result: fmt::Result,
115    has_fields: bool,
116}
117
118pub(super) fn debug_struct_new<'a, 'b>(
119    fmt: &'a mut fmt::Formatter<'b>,
120    name: &str,
121) -> DebugStruct<'a, 'b> {
122    let result = fmt.write_str(name);
123    DebugStruct { fmt, result, has_fields: false }
124}
125
126impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
127    /// Adds a new field to the generated struct output.
128    ///
129    /// # Examples
130    ///
131    /// ```
132    /// use std::fmt;
133    ///
134    /// struct Bar {
135    ///     bar: i32,
136    ///     another: String,
137    /// }
138    ///
139    /// impl fmt::Debug for Bar {
140    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
141    ///         fmt.debug_struct("Bar")
142    ///            .field("bar", &self.bar) // We add `bar` field.
143    ///            .field("another", &self.another) // We add `another` field.
144    ///            // We even add a field which doesn't exist (because why not?).
145    ///            .field("nonexistent_field", &1)
146    ///            .finish() // We're good to go!
147    ///     }
148    /// }
149    ///
150    /// assert_eq!(
151    ///     format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
152    ///     r#"Bar { bar: 10, another: "Hello World", nonexistent_field: 1 }"#,
153    /// );
154    /// ```
155    #[stable(feature = "debug_builders", since = "1.2.0")]
156    pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self {
157        self.result = self.result.and_then(|_| {
158            if self.is_pretty() {
159                if !self.has_fields {
160                    self.fmt.write_str(" {\n")?;
161                }
162                let mut slot = None;
163                let mut state = Default::default();
164                let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
165                writer.write_str(name)?;
166                writer.write_str(": ")?;
167                value.fmt(&mut writer)?;
168                writer.write_str(",\n")
169            } else {
170                let prefix = if self.has_fields { ", " } else { " { " };
171                self.fmt.write_str(prefix)?;
172                self.fmt.write_str(name)?;
173                self.fmt.write_str(": ")?;
174                value.fmt(self.fmt)
175            }
176        });
177
178        self.has_fields = true;
179        self
180    }
181
182    /// Adds a new field to the generated struct output.
183    ///
184    /// This method is equivalent to [`DebugStruct::field`], but formats the
185    /// value using a provided closure rather than by calling [`Debug::fmt`].
186    #[unstable(feature = "debug_closure_helpers", issue = "117729")]
187    pub fn field_with<F>(&mut self, name: &str, value_fmt: F) -> &mut Self
188    where
189        F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
190    {
191        self.field(name, &DebugOnce(Cell::new(Some(value_fmt))))
192    }
193
194    /// Marks the struct as non-exhaustive, indicating to the reader that there are some other
195    /// fields that are not shown in the debug representation.
196    ///
197    /// # Examples
198    ///
199    /// ```
200    /// use std::fmt;
201    ///
202    /// struct Bar {
203    ///     bar: i32,
204    ///     hidden: f32,
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    ///            .finish_non_exhaustive() // Show that some other field(s) exist.
212    ///     }
213    /// }
214    ///
215    /// assert_eq!(
216    ///     format!("{:?}", Bar { bar: 10, hidden: 1.0 }),
217    ///     "Bar { bar: 10, .. }",
218    /// );
219    /// ```
220    #[stable(feature = "debug_non_exhaustive", since = "1.53.0")]
221    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
222        self.result = self.result.and_then(|_| {
223            if self.has_fields {
224                if self.is_pretty() {
225                    let mut slot = None;
226                    let mut state = Default::default();
227                    let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
228                    writer.write_str("..\n")?;
229                    self.fmt.write_str("}")
230                } else {
231                    self.fmt.write_str(", .. }")
232                }
233            } else {
234                self.fmt.write_str(" { .. }")
235            }
236        });
237        self.result
238    }
239
240    /// Finishes output and returns any error encountered.
241    ///
242    /// # Examples
243    ///
244    /// ```
245    /// use std::fmt;
246    ///
247    /// struct Bar {
248    ///     bar: i32,
249    ///     baz: String,
250    /// }
251    ///
252    /// impl fmt::Debug for Bar {
253    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
254    ///         fmt.debug_struct("Bar")
255    ///            .field("bar", &self.bar)
256    ///            .field("baz", &self.baz)
257    ///            .finish() // You need to call it to "finish" the
258    ///                      // struct formatting.
259    ///     }
260    /// }
261    ///
262    /// assert_eq!(
263    ///     format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }),
264    ///     r#"Bar { bar: 10, baz: "Hello World" }"#,
265    /// );
266    /// ```
267    #[stable(feature = "debug_builders", since = "1.2.0")]
268    pub fn finish(&mut self) -> fmt::Result {
269        if self.has_fields {
270            self.result = self.result.and_then(|_| {
271                if self.is_pretty() { self.fmt.write_str("}") } else { self.fmt.write_str(" }") }
272            });
273        }
274        self.result
275    }
276
277    fn is_pretty(&self) -> bool {
278        self.fmt.alternate()
279    }
280}
281
282/// A struct to help with [`fmt::Debug`](Debug) implementations.
283///
284/// This is useful when you wish to output a formatted tuple as a part of your
285/// [`Debug::fmt`] implementation.
286///
287/// This can be constructed by the [`Formatter::debug_tuple`] method.
288///
289/// # Examples
290///
291/// ```
292/// use std::fmt;
293///
294/// struct Foo(i32, String);
295///
296/// impl fmt::Debug for Foo {
297///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
298///         fmt.debug_tuple("Foo")
299///            .field(&self.0)
300///            .field(&self.1)
301///            .finish()
302///     }
303/// }
304///
305/// assert_eq!(
306///     format!("{:?}", Foo(10, "Hello World".to_string())),
307///     r#"Foo(10, "Hello World")"#,
308/// );
309/// ```
310#[must_use = "must eventually call `finish()` on Debug builders"]
311#[allow(missing_debug_implementations)]
312#[stable(feature = "debug_builders", since = "1.2.0")]
313pub struct DebugTuple<'a, 'b: 'a> {
314    fmt: &'a mut fmt::Formatter<'b>,
315    result: fmt::Result,
316    fields: usize,
317    empty_name: bool,
318}
319
320pub(super) fn debug_tuple_new<'a, 'b>(
321    fmt: &'a mut fmt::Formatter<'b>,
322    name: &str,
323) -> DebugTuple<'a, 'b> {
324    let result = fmt.write_str(name);
325    DebugTuple { fmt, result, fields: 0, empty_name: name.is_empty() }
326}
327
328impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
329    /// Adds a new field to the generated tuple struct output.
330    ///
331    /// # Examples
332    ///
333    /// ```
334    /// use std::fmt;
335    ///
336    /// struct Foo(i32, String);
337    ///
338    /// impl fmt::Debug for Foo {
339    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
340    ///         fmt.debug_tuple("Foo")
341    ///            .field(&self.0) // We add the first field.
342    ///            .field(&self.1) // We add the second field.
343    ///            .finish() // We're good to go!
344    ///     }
345    /// }
346    ///
347    /// assert_eq!(
348    ///     format!("{:?}", Foo(10, "Hello World".to_string())),
349    ///     r#"Foo(10, "Hello World")"#,
350    /// );
351    /// ```
352    #[stable(feature = "debug_builders", since = "1.2.0")]
353    pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self {
354        self.result = self.result.and_then(|_| {
355            if self.is_pretty() {
356                if self.fields == 0 {
357                    self.fmt.write_str("(\n")?;
358                }
359                let mut slot = None;
360                let mut state = Default::default();
361                let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
362                value.fmt(&mut writer)?;
363                writer.write_str(",\n")
364            } else {
365                let prefix = if self.fields == 0 { "(" } else { ", " };
366                self.fmt.write_str(prefix)?;
367                value.fmt(self.fmt)
368            }
369        });
370
371        self.fields += 1;
372        self
373    }
374
375    /// Adds a new field to the generated tuple struct output.
376    ///
377    /// This method is equivalent to [`DebugTuple::field`], but formats the
378    /// value using a provided closure rather than by calling [`Debug::fmt`].
379    #[unstable(feature = "debug_closure_helpers", issue = "117729")]
380    pub fn field_with<F>(&mut self, value_fmt: F) -> &mut Self
381    where
382        F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
383    {
384        self.field(&DebugOnce(Cell::new(Some(value_fmt))))
385    }
386
387    /// Marks the tuple struct as non-exhaustive, indicating to the reader that there are some
388    /// other fields that are not shown in the debug representation.
389    ///
390    /// # Examples
391    ///
392    /// ```
393    /// use std::fmt;
394    ///
395    /// struct Foo(i32, String);
396    ///
397    /// impl fmt::Debug for Foo {
398    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
399    ///         fmt.debug_tuple("Foo")
400    ///            .field(&self.0)
401    ///            .finish_non_exhaustive() // Show that some other field(s) exist.
402    ///     }
403    /// }
404    ///
405    /// assert_eq!(
406    ///     format!("{:?}", Foo(10, "secret!".to_owned())),
407    ///     "Foo(10, ..)",
408    /// );
409    /// ```
410    #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
411    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
412        self.result = self.result.and_then(|_| {
413            if self.fields > 0 {
414                if self.is_pretty() {
415                    let mut slot = None;
416                    let mut state = Default::default();
417                    let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
418                    writer.write_str("..\n")?;
419                    self.fmt.write_str(")")
420                } else {
421                    self.fmt.write_str(", ..)")
422                }
423            } else {
424                self.fmt.write_str("(..)")
425            }
426        });
427        self.result
428    }
429
430    /// Finishes output and returns any error encountered.
431    ///
432    /// # Examples
433    ///
434    /// ```
435    /// use std::fmt;
436    ///
437    /// struct Foo(i32, String);
438    ///
439    /// impl fmt::Debug for Foo {
440    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
441    ///         fmt.debug_tuple("Foo")
442    ///            .field(&self.0)
443    ///            .field(&self.1)
444    ///            .finish() // You need to call it to "finish" the
445    ///                      // tuple formatting.
446    ///     }
447    /// }
448    ///
449    /// assert_eq!(
450    ///     format!("{:?}", Foo(10, "Hello World".to_string())),
451    ///     r#"Foo(10, "Hello World")"#,
452    /// );
453    /// ```
454    #[stable(feature = "debug_builders", since = "1.2.0")]
455    pub fn finish(&mut self) -> fmt::Result {
456        if self.fields > 0 {
457            self.result = self.result.and_then(|_| {
458                if self.fields == 1 && self.empty_name && !self.is_pretty() {
459                    self.fmt.write_str(",")?;
460                }
461                self.fmt.write_str(")")
462            });
463        }
464        self.result
465    }
466
467    fn is_pretty(&self) -> bool {
468        self.fmt.alternate()
469    }
470}
471
472/// A helper used to print list-like items with no special formatting.
473struct DebugInner<'a, 'b: 'a> {
474    fmt: &'a mut fmt::Formatter<'b>,
475    result: fmt::Result,
476    has_fields: bool,
477}
478
479impl<'a, 'b: 'a> DebugInner<'a, 'b> {
480    fn entry(&mut self, entry: &dyn fmt::Debug) {
481        self.result = self.result.and_then(|_| {
482            if self.is_pretty() {
483                if !self.has_fields {
484                    self.fmt.write_str("\n")?;
485                }
486                let mut slot = None;
487                let mut state = Default::default();
488                let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
489                entry.fmt(&mut writer)?;
490                writer.write_str(",\n")
491            } else {
492                if self.has_fields {
493                    self.fmt.write_str(", ")?
494                }
495                entry.fmt(self.fmt)
496            }
497        });
498
499        self.has_fields = true;
500    }
501
502    fn entry_with<F>(&mut self, entry_fmt: F)
503    where
504        F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
505    {
506        self.entry(&DebugOnce(Cell::new(Some(entry_fmt))));
507    }
508
509    fn is_pretty(&self) -> bool {
510        self.fmt.alternate()
511    }
512}
513
514/// A struct to help with [`fmt::Debug`](Debug) implementations.
515///
516/// This is useful when you wish to output a formatted set of items as a part
517/// of your [`Debug::fmt`] implementation.
518///
519/// This can be constructed by the [`Formatter::debug_set`] method.
520///
521/// # Examples
522///
523/// ```
524/// use std::fmt;
525///
526/// struct Foo(Vec<i32>);
527///
528/// impl fmt::Debug for Foo {
529///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
530///         fmt.debug_set().entries(self.0.iter()).finish()
531///     }
532/// }
533///
534/// assert_eq!(
535///     format!("{:?}", Foo(vec![10, 11])),
536///     "{10, 11}",
537/// );
538/// ```
539#[must_use = "must eventually call `finish()` on Debug builders"]
540#[allow(missing_debug_implementations)]
541#[stable(feature = "debug_builders", since = "1.2.0")]
542pub struct DebugSet<'a, 'b: 'a> {
543    inner: DebugInner<'a, 'b>,
544}
545
546pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
547    let result = fmt.write_str("{");
548    DebugSet { inner: DebugInner { fmt, result, has_fields: false } }
549}
550
551impl<'a, 'b: 'a> DebugSet<'a, 'b> {
552    /// Adds a new entry to the set output.
553    ///
554    /// # Examples
555    ///
556    /// ```
557    /// use std::fmt;
558    ///
559    /// struct Foo(Vec<i32>, Vec<u32>);
560    ///
561    /// impl fmt::Debug for Foo {
562    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
563    ///         fmt.debug_set()
564    ///            .entry(&self.0) // Adds the first "entry".
565    ///            .entry(&self.1) // Adds the second "entry".
566    ///            .finish()
567    ///     }
568    /// }
569    ///
570    /// assert_eq!(
571    ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
572    ///     "{[10, 11], [12, 13]}",
573    /// );
574    /// ```
575    #[stable(feature = "debug_builders", since = "1.2.0")]
576    pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
577        self.inner.entry(entry);
578        self
579    }
580
581    /// Adds a new entry to the set output.
582    ///
583    /// This method is equivalent to [`DebugSet::entry`], but formats the
584    /// entry using a provided closure rather than by calling [`Debug::fmt`].
585    #[unstable(feature = "debug_closure_helpers", issue = "117729")]
586    pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
587    where
588        F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
589    {
590        self.inner.entry_with(entry_fmt);
591        self
592    }
593
594    /// Adds the contents of an iterator of entries to the set output.
595    ///
596    /// # Examples
597    ///
598    /// ```
599    /// use std::fmt;
600    ///
601    /// struct Foo(Vec<i32>, Vec<u32>);
602    ///
603    /// impl fmt::Debug for Foo {
604    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
605    ///         fmt.debug_set()
606    ///            .entries(self.0.iter()) // Adds the first "entry".
607    ///            .entries(self.1.iter()) // Adds the second "entry".
608    ///            .finish()
609    ///     }
610    /// }
611    ///
612    /// assert_eq!(
613    ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
614    ///     "{10, 11, 12, 13}",
615    /// );
616    /// ```
617    #[stable(feature = "debug_builders", since = "1.2.0")]
618    pub fn entries<D, I>(&mut self, entries: I) -> &mut Self
619    where
620        D: fmt::Debug,
621        I: IntoIterator<Item = D>,
622    {
623        for entry in entries {
624            self.entry(&entry);
625        }
626        self
627    }
628
629    /// Marks the set as non-exhaustive, indicating to the reader that there are some other
630    /// elements that are not shown in the debug representation.
631    ///
632    /// # Examples
633    ///
634    /// ```
635    /// use std::fmt;
636    ///
637    /// struct Foo(Vec<i32>);
638    ///
639    /// impl fmt::Debug for Foo {
640    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
641    ///         // Print at most two elements, abbreviate the rest
642    ///         let mut f = fmt.debug_set();
643    ///         let mut f = f.entries(self.0.iter().take(2));
644    ///         if self.0.len() > 2 {
645    ///             f.finish_non_exhaustive()
646    ///         } else {
647    ///             f.finish()
648    ///         }
649    ///     }
650    /// }
651    ///
652    /// assert_eq!(
653    ///     format!("{:?}", Foo(vec![1, 2, 3, 4])),
654    ///     "{1, 2, ..}",
655    /// );
656    /// ```
657    #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
658    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
659        self.inner.result = self.inner.result.and_then(|_| {
660            if self.inner.has_fields {
661                if self.inner.is_pretty() {
662                    let mut slot = None;
663                    let mut state = Default::default();
664                    let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
665                    writer.write_str("..\n")?;
666                    self.inner.fmt.write_str("}")
667                } else {
668                    self.inner.fmt.write_str(", ..}")
669                }
670            } else {
671                self.inner.fmt.write_str("..}")
672            }
673        });
674        self.inner.result
675    }
676
677    /// Finishes output and returns any error encountered.
678    ///
679    /// # Examples
680    ///
681    /// ```
682    /// use std::fmt;
683    ///
684    /// struct Foo(Vec<i32>);
685    ///
686    /// impl fmt::Debug for Foo {
687    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
688    ///         fmt.debug_set()
689    ///            .entries(self.0.iter())
690    ///            .finish() // Ends the set formatting.
691    ///     }
692    /// }
693    ///
694    /// assert_eq!(
695    ///     format!("{:?}", Foo(vec![10, 11])),
696    ///     "{10, 11}",
697    /// );
698    /// ```
699    #[stable(feature = "debug_builders", since = "1.2.0")]
700    pub fn finish(&mut self) -> fmt::Result {
701        self.inner.result = self.inner.result.and_then(|_| self.inner.fmt.write_str("}"));
702        self.inner.result
703    }
704}
705
706/// A struct to help with [`fmt::Debug`](Debug) implementations.
707///
708/// This is useful when you wish to output a formatted list of items as a part
709/// of your [`Debug::fmt`] implementation.
710///
711/// This can be constructed by the [`Formatter::debug_list`] method.
712///
713/// # Examples
714///
715/// ```
716/// use std::fmt;
717///
718/// struct Foo(Vec<i32>);
719///
720/// impl fmt::Debug for Foo {
721///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
722///         fmt.debug_list().entries(self.0.iter()).finish()
723///     }
724/// }
725///
726/// assert_eq!(
727///     format!("{:?}", Foo(vec![10, 11])),
728///     "[10, 11]",
729/// );
730/// ```
731#[must_use = "must eventually call `finish()` on Debug builders"]
732#[allow(missing_debug_implementations)]
733#[stable(feature = "debug_builders", since = "1.2.0")]
734pub struct DebugList<'a, 'b: 'a> {
735    inner: DebugInner<'a, 'b>,
736}
737
738pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
739    let result = fmt.write_str("[");
740    DebugList { inner: DebugInner { fmt, result, has_fields: false } }
741}
742
743impl<'a, 'b: 'a> DebugList<'a, 'b> {
744    /// Adds a new entry to the list output.
745    ///
746    /// # Examples
747    ///
748    /// ```
749    /// use std::fmt;
750    ///
751    /// struct Foo(Vec<i32>, Vec<u32>);
752    ///
753    /// impl fmt::Debug for Foo {
754    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
755    ///         fmt.debug_list()
756    ///            .entry(&self.0) // We add the first "entry".
757    ///            .entry(&self.1) // We add the second "entry".
758    ///            .finish()
759    ///     }
760    /// }
761    ///
762    /// assert_eq!(
763    ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
764    ///     "[[10, 11], [12, 13]]",
765    /// );
766    /// ```
767    #[stable(feature = "debug_builders", since = "1.2.0")]
768    pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
769        self.inner.entry(entry);
770        self
771    }
772
773    /// Adds a new entry to the list output.
774    ///
775    /// This method is equivalent to [`DebugList::entry`], but formats the
776    /// entry using a provided closure rather than by calling [`Debug::fmt`].
777    #[unstable(feature = "debug_closure_helpers", issue = "117729")]
778    pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
779    where
780        F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
781    {
782        self.inner.entry_with(entry_fmt);
783        self
784    }
785
786    /// Adds the contents of an iterator of entries to the list output.
787    ///
788    /// # Examples
789    ///
790    /// ```
791    /// use std::fmt;
792    ///
793    /// struct Foo(Vec<i32>, Vec<u32>);
794    ///
795    /// impl fmt::Debug for Foo {
796    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
797    ///         fmt.debug_list()
798    ///            .entries(self.0.iter())
799    ///            .entries(self.1.iter())
800    ///            .finish()
801    ///     }
802    /// }
803    ///
804    /// assert_eq!(
805    ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
806    ///     "[10, 11, 12, 13]",
807    /// );
808    /// ```
809    #[stable(feature = "debug_builders", since = "1.2.0")]
810    pub fn entries<D, I>(&mut self, entries: I) -> &mut Self
811    where
812        D: fmt::Debug,
813        I: IntoIterator<Item = D>,
814    {
815        for entry in entries {
816            self.entry(&entry);
817        }
818        self
819    }
820
821    /// Marks the list as non-exhaustive, indicating to the reader that there are some other
822    /// elements that are not shown in the debug representation.
823    ///
824    /// # Examples
825    ///
826    /// ```
827    /// use std::fmt;
828    ///
829    /// struct Foo(Vec<i32>);
830    ///
831    /// impl fmt::Debug for Foo {
832    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
833    ///         // Print at most two elements, abbreviate the rest
834    ///         let mut f = fmt.debug_list();
835    ///         let mut f = f.entries(self.0.iter().take(2));
836    ///         if self.0.len() > 2 {
837    ///             f.finish_non_exhaustive()
838    ///         } else {
839    ///             f.finish()
840    ///         }
841    ///     }
842    /// }
843    ///
844    /// assert_eq!(
845    ///     format!("{:?}", Foo(vec![1, 2, 3, 4])),
846    ///     "[1, 2, ..]",
847    /// );
848    /// ```
849    #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
850    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
851        self.inner.result.and_then(|_| {
852            if self.inner.has_fields {
853                if self.inner.is_pretty() {
854                    let mut slot = None;
855                    let mut state = Default::default();
856                    let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
857                    writer.write_str("..\n")?;
858                    self.inner.fmt.write_str("]")
859                } else {
860                    self.inner.fmt.write_str(", ..]")
861                }
862            } else {
863                self.inner.fmt.write_str("..]")
864            }
865        })
866    }
867
868    /// Finishes output and returns any error encountered.
869    ///
870    /// # Examples
871    ///
872    /// ```
873    /// use std::fmt;
874    ///
875    /// struct Foo(Vec<i32>);
876    ///
877    /// impl fmt::Debug for Foo {
878    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
879    ///         fmt.debug_list()
880    ///            .entries(self.0.iter())
881    ///            .finish() // Ends the list formatting.
882    ///     }
883    /// }
884    ///
885    /// assert_eq!(
886    ///     format!("{:?}", Foo(vec![10, 11])),
887    ///     "[10, 11]",
888    /// );
889    /// ```
890    #[stable(feature = "debug_builders", since = "1.2.0")]
891    pub fn finish(&mut self) -> fmt::Result {
892        self.inner.result = self.inner.result.and_then(|_| self.inner.fmt.write_str("]"));
893        self.inner.result
894    }
895}
896
897/// A struct to help with [`fmt::Debug`](Debug) implementations.
898///
899/// This is useful when you wish to output a formatted map as a part of your
900/// [`Debug::fmt`] implementation.
901///
902/// This can be constructed by the [`Formatter::debug_map`] method.
903///
904/// # Examples
905///
906/// ```
907/// use std::fmt;
908///
909/// struct Foo(Vec<(String, i32)>);
910///
911/// impl fmt::Debug for Foo {
912///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
913///         fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish()
914///     }
915/// }
916///
917/// assert_eq!(
918///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
919///     r#"{"A": 10, "B": 11}"#,
920/// );
921/// ```
922#[must_use = "must eventually call `finish()` on Debug builders"]
923#[allow(missing_debug_implementations)]
924#[stable(feature = "debug_builders", since = "1.2.0")]
925pub struct DebugMap<'a, 'b: 'a> {
926    fmt: &'a mut fmt::Formatter<'b>,
927    result: fmt::Result,
928    has_fields: bool,
929    has_key: bool,
930    // The state of newlines is tracked between keys and values
931    state: PadAdapterState,
932}
933
934pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
935    let result = fmt.write_str("{");
936    DebugMap { fmt, result, has_fields: false, has_key: false, state: Default::default() }
937}
938
939impl<'a, 'b: 'a> DebugMap<'a, 'b> {
940    /// Adds a new entry to the map output.
941    ///
942    /// # Examples
943    ///
944    /// ```
945    /// use std::fmt;
946    ///
947    /// struct Foo(Vec<(String, i32)>);
948    ///
949    /// impl fmt::Debug for Foo {
950    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
951    ///         fmt.debug_map()
952    ///            .entry(&"whole", &self.0) // We add the "whole" entry.
953    ///            .finish()
954    ///     }
955    /// }
956    ///
957    /// assert_eq!(
958    ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
959    ///     r#"{"whole": [("A", 10), ("B", 11)]}"#,
960    /// );
961    /// ```
962    #[stable(feature = "debug_builders", since = "1.2.0")]
963    pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut Self {
964        self.key(key).value(value)
965    }
966
967    /// Adds the key part of a new entry to the map output.
968    ///
969    /// This method, together with `value`, is an alternative to `entry` that
970    /// can be used when the complete entry isn't known upfront. Prefer the `entry`
971    /// method when it's possible to use.
972    ///
973    /// # Panics
974    ///
975    /// `key` must be called before `value` and each call to `key` must be followed
976    /// by a corresponding call to `value`. Otherwise this method will panic.
977    ///
978    /// # Examples
979    ///
980    /// ```
981    /// use std::fmt;
982    ///
983    /// struct Foo(Vec<(String, i32)>);
984    ///
985    /// impl fmt::Debug for Foo {
986    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
987    ///         fmt.debug_map()
988    ///            .key(&"whole").value(&self.0) // We add the "whole" entry.
989    ///            .finish()
990    ///     }
991    /// }
992    ///
993    /// assert_eq!(
994    ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
995    ///     r#"{"whole": [("A", 10), ("B", 11)]}"#,
996    /// );
997    /// ```
998    #[stable(feature = "debug_map_key_value", since = "1.42.0")]
999    pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self {
1000        self.result = self.result.and_then(|_| {
1001            assert!(
1002                !self.has_key,
1003                "attempted to begin a new map entry \
1004                                    without completing the previous one"
1005            );
1006
1007            if self.is_pretty() {
1008                if !self.has_fields {
1009                    self.fmt.write_str("\n")?;
1010                }
1011                let mut slot = None;
1012                self.state = Default::default();
1013                let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
1014                key.fmt(&mut writer)?;
1015                writer.write_str(": ")?;
1016            } else {
1017                if self.has_fields {
1018                    self.fmt.write_str(", ")?
1019                }
1020                key.fmt(self.fmt)?;
1021                self.fmt.write_str(": ")?;
1022            }
1023
1024            self.has_key = true;
1025            Ok(())
1026        });
1027
1028        self
1029    }
1030
1031    /// Adds the key part of a new entry to the map output.
1032    ///
1033    /// This method is equivalent to [`DebugMap::key`], but formats the
1034    /// key using a provided closure rather than by calling [`Debug::fmt`].
1035    #[unstable(feature = "debug_closure_helpers", issue = "117729")]
1036    pub fn key_with<F>(&mut self, key_fmt: F) -> &mut Self
1037    where
1038        F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
1039    {
1040        self.key(&DebugOnce(Cell::new(Some(key_fmt))))
1041    }
1042
1043    /// Adds the value part of a new entry to the map output.
1044    ///
1045    /// This method, together with `key`, is an alternative to `entry` that
1046    /// can be used when the complete entry isn't known upfront. Prefer the `entry`
1047    /// method when it's possible to use.
1048    ///
1049    /// # Panics
1050    ///
1051    /// `key` must be called before `value` and each call to `key` must be followed
1052    /// by a corresponding call to `value`. Otherwise this method will panic.
1053    ///
1054    /// # Examples
1055    ///
1056    /// ```
1057    /// use std::fmt;
1058    ///
1059    /// struct Foo(Vec<(String, i32)>);
1060    ///
1061    /// impl fmt::Debug for Foo {
1062    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1063    ///         fmt.debug_map()
1064    ///            .key(&"whole").value(&self.0) // We add the "whole" entry.
1065    ///            .finish()
1066    ///     }
1067    /// }
1068    ///
1069    /// assert_eq!(
1070    ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1071    ///     r#"{"whole": [("A", 10), ("B", 11)]}"#,
1072    /// );
1073    /// ```
1074    #[stable(feature = "debug_map_key_value", since = "1.42.0")]
1075    pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self {
1076        self.result = self.result.and_then(|_| {
1077            assert!(self.has_key, "attempted to format a map value before its key");
1078
1079            if self.is_pretty() {
1080                let mut slot = None;
1081                let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
1082                value.fmt(&mut writer)?;
1083                writer.write_str(",\n")?;
1084            } else {
1085                value.fmt(self.fmt)?;
1086            }
1087
1088            self.has_key = false;
1089            Ok(())
1090        });
1091
1092        self.has_fields = true;
1093        self
1094    }
1095
1096    /// Adds the value part of a new entry to the map output.
1097    ///
1098    /// This method is equivalent to [`DebugMap::value`], but formats the
1099    /// value using a provided closure rather than by calling [`Debug::fmt`].
1100    #[unstable(feature = "debug_closure_helpers", issue = "117729")]
1101    pub fn value_with<F>(&mut self, value_fmt: F) -> &mut Self
1102    where
1103        F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
1104    {
1105        self.value(&DebugOnce(Cell::new(Some(value_fmt))))
1106    }
1107
1108    /// Adds the contents of an iterator of entries to the map output.
1109    ///
1110    /// # Examples
1111    ///
1112    /// ```
1113    /// use std::fmt;
1114    ///
1115    /// struct Foo(Vec<(String, i32)>);
1116    ///
1117    /// impl fmt::Debug for Foo {
1118    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1119    ///         fmt.debug_map()
1120    ///            // We map our vec so each entries' first field will become
1121    ///            // the "key".
1122    ///            .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
1123    ///            .finish()
1124    ///     }
1125    /// }
1126    ///
1127    /// assert_eq!(
1128    ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1129    ///     r#"{"A": 10, "B": 11}"#,
1130    /// );
1131    /// ```
1132    #[stable(feature = "debug_builders", since = "1.2.0")]
1133    pub fn entries<K, V, I>(&mut self, entries: I) -> &mut Self
1134    where
1135        K: fmt::Debug,
1136        V: fmt::Debug,
1137        I: IntoIterator<Item = (K, V)>,
1138    {
1139        for (k, v) in entries {
1140            self.entry(&k, &v);
1141        }
1142        self
1143    }
1144
1145    /// Marks the map as non-exhaustive, indicating to the reader that there are some other
1146    /// entries that are not shown in the debug representation.
1147    ///
1148    /// # Examples
1149    ///
1150    /// ```
1151    /// use std::fmt;
1152    ///
1153    /// struct Foo(Vec<(String, i32)>);
1154    ///
1155    /// impl fmt::Debug for Foo {
1156    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1157    ///         // Print at most two elements, abbreviate the rest
1158    ///         let mut f = fmt.debug_map();
1159    ///         let mut f = f.entries(self.0.iter().take(2).map(|&(ref k, ref v)| (k, v)));
1160    ///         if self.0.len() > 2 {
1161    ///             f.finish_non_exhaustive()
1162    ///         } else {
1163    ///             f.finish()
1164    ///         }
1165    ///     }
1166    /// }
1167    ///
1168    /// assert_eq!(
1169    ///     format!("{:?}", Foo(vec![
1170    ///         ("A".to_string(), 10),
1171    ///         ("B".to_string(), 11),
1172    ///         ("C".to_string(), 12),
1173    ///     ])),
1174    ///     r#"{"A": 10, "B": 11, ..}"#,
1175    /// );
1176    /// ```
1177    #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
1178    pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
1179        self.result = self.result.and_then(|_| {
1180            assert!(!self.has_key, "attempted to finish a map with a partial entry");
1181
1182            if self.has_fields {
1183                if self.is_pretty() {
1184                    let mut slot = None;
1185                    let mut state = Default::default();
1186                    let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
1187                    writer.write_str("..\n")?;
1188                    self.fmt.write_str("}")
1189                } else {
1190                    self.fmt.write_str(", ..}")
1191                }
1192            } else {
1193                self.fmt.write_str("..}")
1194            }
1195        });
1196        self.result
1197    }
1198
1199    /// Finishes output and returns any error encountered.
1200    ///
1201    /// # Panics
1202    ///
1203    /// `key` must be called before `value` and each call to `key` must be followed
1204    /// by a corresponding call to `value`. Otherwise this method will panic.
1205    ///
1206    /// # Examples
1207    ///
1208    /// ```
1209    /// use std::fmt;
1210    ///
1211    /// struct Foo(Vec<(String, i32)>);
1212    ///
1213    /// impl fmt::Debug for Foo {
1214    ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1215    ///         fmt.debug_map()
1216    ///            .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
1217    ///            .finish() // Ends the map formatting.
1218    ///     }
1219    /// }
1220    ///
1221    /// assert_eq!(
1222    ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1223    ///     r#"{"A": 10, "B": 11}"#,
1224    /// );
1225    /// ```
1226    #[stable(feature = "debug_builders", since = "1.2.0")]
1227    pub fn finish(&mut self) -> fmt::Result {
1228        self.result = self.result.and_then(|_| {
1229            assert!(!self.has_key, "attempted to finish a map with a partial entry");
1230
1231            self.fmt.write_str("}")
1232        });
1233        self.result
1234    }
1235
1236    fn is_pretty(&self) -> bool {
1237        self.fmt.alternate()
1238    }
1239}
1240
1241/// Creates a type whose [`fmt::Debug`] and [`fmt::Display`] impls are
1242/// forwarded to the provided closure.
1243///
1244/// # Examples
1245///
1246/// ```
1247/// use std::fmt;
1248///
1249/// let value = 'a';
1250/// assert_eq!(format!("{}", value), "a");
1251/// assert_eq!(format!("{:?}", value), "'a'");
1252///
1253/// let wrapped = fmt::from_fn(|f| write!(f, "{value:?}"));
1254/// assert_eq!(format!("{}", wrapped), "'a'");
1255/// assert_eq!(format!("{:?}", wrapped), "'a'");
1256/// ```
1257#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1258#[rustc_const_stable(feature = "const_fmt_from_fn", since = "1.95.0")]
1259#[must_use = "returns a type implementing Debug and Display, which do not have any effects unless they are used"]
1260pub const fn from_fn<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result>(f: F) -> FromFn<F> {
1261    FromFn(f)
1262}
1263
1264/// Implements [`fmt::Debug`] and [`fmt::Display`] via the provided closure.
1265///
1266/// Created with [`from_fn`].
1267#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1268pub struct FromFn<F>(F);
1269
1270#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1271impl<F> fmt::Debug for FromFn<F>
1272where
1273    F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
1274{
1275    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1276        (self.0)(f)
1277    }
1278}
1279
1280#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1281impl<F> fmt::Display for FromFn<F>
1282where
1283    F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
1284{
1285    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1286        (self.0)(f)
1287    }
1288}