Skip to main content

core/fmt/
builders.rs

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