core/fmt/
builders.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy