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