Skip to main content

core/fmt/
builders.rs

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