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 ///
187 /// # Examples
188 ///
189 /// ```
190 /// #![feature(debug_closure_helpers)]
191 ///
192 /// use std::fmt;
193 ///
194 /// struct Bar {
195 /// bar: i32,
196 /// another: String,
197 /// }
198 ///
199 /// impl fmt::Debug for Bar {
200 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
201 /// fmt.debug_struct("Bar")
202 /// // Print `bar` as a hex value
203 /// .field_with("bar", |fmt| write!(fmt, "{:#010x}", &self.bar))
204 /// .field("another", &self.another)
205 /// .finish()
206 /// }
207 /// }
208 ///
209 /// assert_eq!(
210 /// format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
211 /// r#"Bar { bar: 0x0000000a, another: "Hello World" }"#,
212 /// );
213 /// ```
214 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
215 pub fn field_with<F>(&mut self, name: &str, value_fmt: F) -> &mut Self
216 where
217 F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
218 {
219 self.field(name, &DebugOnce(Cell::new(Some(value_fmt))))
220 }
221
222 /// Marks the struct as non-exhaustive, indicating to the reader that there are some other
223 /// fields that are not shown in the debug representation.
224 ///
225 /// # Examples
226 ///
227 /// ```
228 /// use std::fmt;
229 ///
230 /// struct Bar {
231 /// bar: i32,
232 /// hidden: f32,
233 /// }
234 ///
235 /// impl fmt::Debug for Bar {
236 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
237 /// fmt.debug_struct("Bar")
238 /// .field("bar", &self.bar)
239 /// .finish_non_exhaustive() // Show that some other field(s) exist.
240 /// }
241 /// }
242 ///
243 /// assert_eq!(
244 /// format!("{:?}", Bar { bar: 10, hidden: 1.0 }),
245 /// "Bar { bar: 10, .. }",
246 /// );
247 /// ```
248 #[stable(feature = "debug_non_exhaustive", since = "1.53.0")]
249 pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
250 self.result = self.result.and_then(|_| {
251 if self.has_fields {
252 if self.is_pretty() {
253 let mut slot = None;
254 let mut state = Default::default();
255 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
256 writer.write_str("..\n")?;
257 self.fmt.write_str("}")
258 } else {
259 self.fmt.write_str(", .. }")
260 }
261 } else {
262 self.fmt.write_str(" { .. }")
263 }
264 });
265 self.result
266 }
267
268 /// Finishes output and returns any error encountered.
269 ///
270 /// # Examples
271 ///
272 /// ```
273 /// use std::fmt;
274 ///
275 /// struct Bar {
276 /// bar: i32,
277 /// baz: String,
278 /// }
279 ///
280 /// impl fmt::Debug for Bar {
281 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
282 /// fmt.debug_struct("Bar")
283 /// .field("bar", &self.bar)
284 /// .field("baz", &self.baz)
285 /// .finish() // You need to call it to "finish" the
286 /// // struct formatting.
287 /// }
288 /// }
289 ///
290 /// assert_eq!(
291 /// format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }),
292 /// r#"Bar { bar: 10, baz: "Hello World" }"#,
293 /// );
294 /// ```
295 #[stable(feature = "debug_builders", since = "1.2.0")]
296 pub fn finish(&mut self) -> fmt::Result {
297 if self.has_fields {
298 self.result = self.result.and_then(|_| {
299 if self.is_pretty() { self.fmt.write_str("}") } else { self.fmt.write_str(" }") }
300 });
301 }
302 self.result
303 }
304
305 fn is_pretty(&self) -> bool {
306 self.fmt.alternate()
307 }
308}
309
310/// A struct to help with [`fmt::Debug`](Debug) implementations.
311///
312/// This is useful when you wish to output a formatted tuple as a part of your
313/// [`Debug::fmt`] implementation.
314///
315/// This can be constructed by the [`Formatter::debug_tuple`] method.
316///
317/// # Examples
318///
319/// ```
320/// use std::fmt;
321///
322/// struct Foo(i32, String);
323///
324/// impl fmt::Debug for Foo {
325/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
326/// fmt.debug_tuple("Foo")
327/// .field(&self.0)
328/// .field(&self.1)
329/// .finish()
330/// }
331/// }
332///
333/// assert_eq!(
334/// format!("{:?}", Foo(10, "Hello World".to_string())),
335/// r#"Foo(10, "Hello World")"#,
336/// );
337/// ```
338#[must_use = "must eventually call `finish()` on Debug builders"]
339#[allow(missing_debug_implementations)]
340#[stable(feature = "debug_builders", since = "1.2.0")]
341pub struct DebugTuple<'a, 'b: 'a> {
342 fmt: &'a mut fmt::Formatter<'b>,
343 result: fmt::Result,
344 fields: usize,
345 empty_name: bool,
346}
347
348pub(super) fn debug_tuple_new<'a, 'b>(
349 fmt: &'a mut fmt::Formatter<'b>,
350 name: &str,
351) -> DebugTuple<'a, 'b> {
352 let result = fmt.write_str(name);
353 DebugTuple { fmt, result, fields: 0, empty_name: name.is_empty() }
354}
355
356impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
357 /// Adds a new field to the generated tuple struct output.
358 ///
359 /// # Examples
360 ///
361 /// ```
362 /// use std::fmt;
363 ///
364 /// struct Foo(i32, String);
365 ///
366 /// impl fmt::Debug for Foo {
367 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
368 /// fmt.debug_tuple("Foo")
369 /// .field(&self.0) // We add the first field.
370 /// .field(&self.1) // We add the second field.
371 /// .finish() // We're good to go!
372 /// }
373 /// }
374 ///
375 /// assert_eq!(
376 /// format!("{:?}", Foo(10, "Hello World".to_string())),
377 /// r#"Foo(10, "Hello World")"#,
378 /// );
379 /// ```
380 #[stable(feature = "debug_builders", since = "1.2.0")]
381 pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self {
382 self.result = self.result.and_then(|_| {
383 if self.is_pretty() {
384 if self.fields == 0 {
385 self.fmt.write_str("(\n")?;
386 }
387 let mut slot = None;
388 let mut state = Default::default();
389 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
390 value.fmt(&mut writer)?;
391 writer.write_str(",\n")
392 } else {
393 let prefix = if self.fields == 0 { "(" } else { ", " };
394 self.fmt.write_str(prefix)?;
395 value.fmt(self.fmt)
396 }
397 });
398
399 self.fields += 1;
400 self
401 }
402
403 /// Adds a new field to the generated tuple struct output.
404 ///
405 /// This method is equivalent to [`DebugTuple::field`], but formats the
406 /// value using a provided closure rather than by calling [`Debug::fmt`].
407 ///
408 /// # Examples
409 ///
410 /// ```
411 /// #![feature(debug_closure_helpers)]
412 ///
413 /// use std::fmt;
414 ///
415 /// struct Foo(i32, String);
416 ///
417 /// impl fmt::Debug for Foo {
418 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
419 /// fmt.debug_tuple("Foo")
420 /// // Print the first field as a hex value
421 /// .field_with(|fmt| write!(fmt, "{:#010x}", &self.0))
422 /// .field(&self.1)
423 /// .finish()
424 /// }
425 /// }
426 ///
427 /// assert_eq!(
428 /// format!("{:?}", Foo(10, "Hello World".to_string())),
429 /// r#"Foo(0x0000000a, "Hello World")"#,
430 /// );
431 /// ```
432 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
433 pub fn field_with<F>(&mut self, value_fmt: F) -> &mut Self
434 where
435 F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
436 {
437 self.field(&DebugOnce(Cell::new(Some(value_fmt))))
438 }
439
440 /// Marks the tuple struct as non-exhaustive, indicating to the reader that there are some
441 /// other fields that are not shown in the debug representation.
442 ///
443 /// # Examples
444 ///
445 /// ```
446 /// use std::fmt;
447 ///
448 /// struct Foo(i32, String);
449 ///
450 /// impl fmt::Debug for Foo {
451 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
452 /// fmt.debug_tuple("Foo")
453 /// .field(&self.0)
454 /// .finish_non_exhaustive() // Show that some other field(s) exist.
455 /// }
456 /// }
457 ///
458 /// assert_eq!(
459 /// format!("{:?}", Foo(10, "secret!".to_owned())),
460 /// "Foo(10, ..)",
461 /// );
462 /// ```
463 #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
464 pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
465 self.result = self.result.and_then(|_| {
466 if self.fields > 0 {
467 if self.is_pretty() {
468 let mut slot = None;
469 let mut state = Default::default();
470 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
471 writer.write_str("..\n")?;
472 self.fmt.write_str(")")
473 } else {
474 self.fmt.write_str(", ..)")
475 }
476 } else {
477 self.fmt.write_str("(..)")
478 }
479 });
480 self.result
481 }
482
483 /// Finishes output and returns any error encountered.
484 ///
485 /// # Examples
486 ///
487 /// ```
488 /// use std::fmt;
489 ///
490 /// struct Foo(i32, String);
491 ///
492 /// impl fmt::Debug for Foo {
493 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
494 /// fmt.debug_tuple("Foo")
495 /// .field(&self.0)
496 /// .field(&self.1)
497 /// .finish() // You need to call it to "finish" the
498 /// // tuple formatting.
499 /// }
500 /// }
501 ///
502 /// assert_eq!(
503 /// format!("{:?}", Foo(10, "Hello World".to_string())),
504 /// r#"Foo(10, "Hello World")"#,
505 /// );
506 /// ```
507 #[stable(feature = "debug_builders", since = "1.2.0")]
508 pub fn finish(&mut self) -> fmt::Result {
509 if self.fields > 0 {
510 self.result = self.result.and_then(|_| {
511 if self.fields == 1 && self.empty_name && !self.is_pretty() {
512 self.fmt.write_str(",")?;
513 }
514 self.fmt.write_str(")")
515 });
516 }
517 self.result
518 }
519
520 fn is_pretty(&self) -> bool {
521 self.fmt.alternate()
522 }
523}
524
525/// A helper used to print list-like items with no special formatting.
526struct DebugInner<'a, 'b: 'a> {
527 fmt: &'a mut fmt::Formatter<'b>,
528 result: fmt::Result,
529 has_fields: bool,
530}
531
532impl<'a, 'b: 'a> DebugInner<'a, 'b> {
533 fn entry(&mut self, entry: &dyn fmt::Debug) {
534 self.result = self.result.and_then(|_| {
535 if self.is_pretty() {
536 if !self.has_fields {
537 self.fmt.write_str("\n")?;
538 }
539 let mut slot = None;
540 let mut state = Default::default();
541 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
542 entry.fmt(&mut writer)?;
543 writer.write_str(",\n")
544 } else {
545 if self.has_fields {
546 self.fmt.write_str(", ")?
547 }
548 entry.fmt(self.fmt)
549 }
550 });
551
552 self.has_fields = true;
553 }
554
555 fn entry_with<F>(&mut self, entry_fmt: F)
556 where
557 F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
558 {
559 self.entry(&DebugOnce(Cell::new(Some(entry_fmt))));
560 }
561
562 fn is_pretty(&self) -> bool {
563 self.fmt.alternate()
564 }
565}
566
567/// A struct to help with [`fmt::Debug`](Debug) implementations.
568///
569/// This is useful when you wish to output a formatted set of items as a part
570/// of your [`Debug::fmt`] implementation.
571///
572/// This can be constructed by the [`Formatter::debug_set`] method.
573///
574/// # Examples
575///
576/// ```
577/// use std::fmt;
578///
579/// struct Foo(Vec<i32>);
580///
581/// impl fmt::Debug for Foo {
582/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
583/// fmt.debug_set().entries(self.0.iter()).finish()
584/// }
585/// }
586///
587/// assert_eq!(
588/// format!("{:?}", Foo(vec![10, 11])),
589/// "{10, 11}",
590/// );
591/// ```
592#[must_use = "must eventually call `finish()` on Debug builders"]
593#[allow(missing_debug_implementations)]
594#[stable(feature = "debug_builders", since = "1.2.0")]
595pub struct DebugSet<'a, 'b: 'a> {
596 inner: DebugInner<'a, 'b>,
597}
598
599pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
600 let result = fmt.write_str("{");
601 DebugSet { inner: DebugInner { fmt, result, has_fields: false } }
602}
603
604impl<'a, 'b: 'a> DebugSet<'a, 'b> {
605 /// Adds a new entry to the set output.
606 ///
607 /// # Examples
608 ///
609 /// ```
610 /// use std::fmt;
611 ///
612 /// struct Foo(Vec<i32>, Vec<u32>);
613 ///
614 /// impl fmt::Debug for Foo {
615 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
616 /// fmt.debug_set()
617 /// .entry(&self.0) // Adds the first "entry".
618 /// .entry(&self.1) // Adds the second "entry".
619 /// .finish()
620 /// }
621 /// }
622 ///
623 /// assert_eq!(
624 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
625 /// "{[10, 11], [12, 13]}",
626 /// );
627 /// ```
628 #[stable(feature = "debug_builders", since = "1.2.0")]
629 pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
630 self.inner.entry(entry);
631 self
632 }
633
634 /// Adds a new entry to the set output.
635 ///
636 /// This method is equivalent to [`DebugSet::entry`], but formats the
637 /// entry using a provided closure rather than by calling [`Debug::fmt`].
638 ///
639 /// # Examples
640 ///
641 /// ```
642 /// #![feature(debug_closure_helpers)]
643 ///
644 /// use std::fmt;
645 ///
646 /// struct Foo(Vec<i32>, Vec<u32>);
647 ///
648 /// impl fmt::Debug for Foo {
649 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
650 /// fmt.debug_set()
651 /// .entry(&self.0)
652 /// // Print the second member as a set
653 /// .entry_with(|fmt| fmt.debug_set().entries(&self.1).finish())
654 /// .finish()
655 /// }
656 /// }
657 ///
658 /// assert_eq!(
659 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
660 /// "{[10, 11], {12, 13}}",
661 /// );
662 /// ```
663 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
664 pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
665 where
666 F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
667 {
668 self.inner.entry_with(entry_fmt);
669 self
670 }
671
672 /// Adds the contents of an iterator of entries to the set output.
673 ///
674 /// # Examples
675 ///
676 /// ```
677 /// use std::fmt;
678 ///
679 /// struct Foo(Vec<i32>, Vec<u32>);
680 ///
681 /// impl fmt::Debug for Foo {
682 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
683 /// fmt.debug_set()
684 /// .entries(self.0.iter()) // Adds the first "entry".
685 /// .entries(self.1.iter()) // Adds the second "entry".
686 /// .finish()
687 /// }
688 /// }
689 ///
690 /// assert_eq!(
691 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
692 /// "{10, 11, 12, 13}",
693 /// );
694 /// ```
695 #[stable(feature = "debug_builders", since = "1.2.0")]
696 pub fn entries<D, I>(&mut self, entries: I) -> &mut Self
697 where
698 D: fmt::Debug,
699 I: IntoIterator<Item = D>,
700 {
701 for entry in entries {
702 self.entry(&entry);
703 }
704 self
705 }
706
707 /// Marks the set as non-exhaustive, indicating to the reader that there are some other
708 /// elements that are not shown in the debug representation.
709 ///
710 /// # Examples
711 ///
712 /// ```
713 /// use std::fmt;
714 ///
715 /// struct Foo(Vec<i32>);
716 ///
717 /// impl fmt::Debug for Foo {
718 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
719 /// // Print at most two elements, abbreviate the rest
720 /// let mut f = fmt.debug_set();
721 /// let mut f = f.entries(self.0.iter().take(2));
722 /// if self.0.len() > 2 {
723 /// f.finish_non_exhaustive()
724 /// } else {
725 /// f.finish()
726 /// }
727 /// }
728 /// }
729 ///
730 /// assert_eq!(
731 /// format!("{:?}", Foo(vec![1, 2, 3, 4])),
732 /// "{1, 2, ..}",
733 /// );
734 /// ```
735 #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
736 pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
737 self.inner.result = self.inner.result.and_then(|_| {
738 if self.inner.has_fields {
739 if self.inner.is_pretty() {
740 let mut slot = None;
741 let mut state = Default::default();
742 let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
743 writer.write_str("..\n")?;
744 self.inner.fmt.write_str("}")
745 } else {
746 self.inner.fmt.write_str(", ..}")
747 }
748 } else {
749 self.inner.fmt.write_str("..}")
750 }
751 });
752 self.inner.result
753 }
754
755 /// Finishes output and returns any error encountered.
756 ///
757 /// # Examples
758 ///
759 /// ```
760 /// use std::fmt;
761 ///
762 /// struct Foo(Vec<i32>);
763 ///
764 /// impl fmt::Debug for Foo {
765 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
766 /// fmt.debug_set()
767 /// .entries(self.0.iter())
768 /// .finish() // Ends the set formatting.
769 /// }
770 /// }
771 ///
772 /// assert_eq!(
773 /// format!("{:?}", Foo(vec![10, 11])),
774 /// "{10, 11}",
775 /// );
776 /// ```
777 #[stable(feature = "debug_builders", since = "1.2.0")]
778 pub fn finish(&mut self) -> fmt::Result {
779 self.inner.result = self.inner.result.and_then(|_| self.inner.fmt.write_str("}"));
780 self.inner.result
781 }
782}
783
784/// A struct to help with [`fmt::Debug`](Debug) implementations.
785///
786/// This is useful when you wish to output a formatted list of items as a part
787/// of your [`Debug::fmt`] implementation.
788///
789/// This can be constructed by the [`Formatter::debug_list`] method.
790///
791/// # Examples
792///
793/// ```
794/// use std::fmt;
795///
796/// struct Foo(Vec<i32>);
797///
798/// impl fmt::Debug for Foo {
799/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
800/// fmt.debug_list().entries(self.0.iter()).finish()
801/// }
802/// }
803///
804/// assert_eq!(
805/// format!("{:?}", Foo(vec![10, 11])),
806/// "[10, 11]",
807/// );
808/// ```
809#[must_use = "must eventually call `finish()` on Debug builders"]
810#[allow(missing_debug_implementations)]
811#[stable(feature = "debug_builders", since = "1.2.0")]
812pub struct DebugList<'a, 'b: 'a> {
813 inner: DebugInner<'a, 'b>,
814}
815
816pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
817 let result = fmt.write_str("[");
818 DebugList { inner: DebugInner { fmt, result, has_fields: false } }
819}
820
821impl<'a, 'b: 'a> DebugList<'a, 'b> {
822 /// Adds a new entry to the list output.
823 ///
824 /// # Examples
825 ///
826 /// ```
827 /// use std::fmt;
828 ///
829 /// struct Foo(Vec<i32>, Vec<u32>);
830 ///
831 /// impl fmt::Debug for Foo {
832 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
833 /// fmt.debug_list()
834 /// .entry(&self.0) // We add the first "entry".
835 /// .entry(&self.1) // We add the second "entry".
836 /// .finish()
837 /// }
838 /// }
839 ///
840 /// assert_eq!(
841 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
842 /// "[[10, 11], [12, 13]]",
843 /// );
844 /// ```
845 #[stable(feature = "debug_builders", since = "1.2.0")]
846 pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
847 self.inner.entry(entry);
848 self
849 }
850
851 /// Adds a new entry to the list output.
852 ///
853 /// This method is equivalent to [`DebugList::entry`], but formats the
854 /// entry using a provided closure rather than by calling [`Debug::fmt`].
855 ///
856 /// # Examples
857 ///
858 /// ```
859 /// #![feature(debug_closure_helpers)]
860 ///
861 /// use std::fmt;
862 ///
863 /// struct Foo(Vec<i32>, Vec<u32>);
864 ///
865 /// impl fmt::Debug for Foo {
866 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
867 /// fmt.debug_list()
868 /// .entry(&self.0)
869 /// // Print the second member as a set
870 /// .entry_with(|fmt| fmt.debug_set().entries(&self.1).finish())
871 /// .finish()
872 /// }
873 /// }
874 ///
875 /// assert_eq!(
876 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
877 /// "[[10, 11], {12, 13}]",
878 /// );
879 /// ```
880 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
881 pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
882 where
883 F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
884 {
885 self.inner.entry_with(entry_fmt);
886 self
887 }
888
889 /// Adds the contents of an iterator of entries to the list output.
890 ///
891 /// # Examples
892 ///
893 /// ```
894 /// use std::fmt;
895 ///
896 /// struct Foo(Vec<i32>, Vec<u32>);
897 ///
898 /// impl fmt::Debug for Foo {
899 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
900 /// fmt.debug_list()
901 /// .entries(self.0.iter())
902 /// .entries(self.1.iter())
903 /// .finish()
904 /// }
905 /// }
906 ///
907 /// assert_eq!(
908 /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
909 /// "[10, 11, 12, 13]",
910 /// );
911 /// ```
912 #[stable(feature = "debug_builders", since = "1.2.0")]
913 pub fn entries<D, I>(&mut self, entries: I) -> &mut Self
914 where
915 D: fmt::Debug,
916 I: IntoIterator<Item = D>,
917 {
918 for entry in entries {
919 self.entry(&entry);
920 }
921 self
922 }
923
924 /// Marks the list as non-exhaustive, indicating to the reader that there are some other
925 /// elements that are not shown in the debug representation.
926 ///
927 /// # Examples
928 ///
929 /// ```
930 /// use std::fmt;
931 ///
932 /// struct Foo(Vec<i32>);
933 ///
934 /// impl fmt::Debug for Foo {
935 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
936 /// // Print at most two elements, abbreviate the rest
937 /// let mut f = fmt.debug_list();
938 /// let mut f = f.entries(self.0.iter().take(2));
939 /// if self.0.len() > 2 {
940 /// f.finish_non_exhaustive()
941 /// } else {
942 /// f.finish()
943 /// }
944 /// }
945 /// }
946 ///
947 /// assert_eq!(
948 /// format!("{:?}", Foo(vec![1, 2, 3, 4])),
949 /// "[1, 2, ..]",
950 /// );
951 /// ```
952 #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
953 pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
954 self.inner.result.and_then(|_| {
955 if self.inner.has_fields {
956 if self.inner.is_pretty() {
957 let mut slot = None;
958 let mut state = Default::default();
959 let mut writer = PadAdapter::wrap(self.inner.fmt, &mut slot, &mut state);
960 writer.write_str("..\n")?;
961 self.inner.fmt.write_str("]")
962 } else {
963 self.inner.fmt.write_str(", ..]")
964 }
965 } else {
966 self.inner.fmt.write_str("..]")
967 }
968 })
969 }
970
971 /// Finishes output and returns any error encountered.
972 ///
973 /// # Examples
974 ///
975 /// ```
976 /// use std::fmt;
977 ///
978 /// struct Foo(Vec<i32>);
979 ///
980 /// impl fmt::Debug for Foo {
981 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
982 /// fmt.debug_list()
983 /// .entries(self.0.iter())
984 /// .finish() // Ends the list formatting.
985 /// }
986 /// }
987 ///
988 /// assert_eq!(
989 /// format!("{:?}", Foo(vec![10, 11])),
990 /// "[10, 11]",
991 /// );
992 /// ```
993 #[stable(feature = "debug_builders", since = "1.2.0")]
994 pub fn finish(&mut self) -> fmt::Result {
995 self.inner.result = self.inner.result.and_then(|_| self.inner.fmt.write_str("]"));
996 self.inner.result
997 }
998}
999
1000/// A struct to help with [`fmt::Debug`](Debug) implementations.
1001///
1002/// This is useful when you wish to output a formatted map as a part of your
1003/// [`Debug::fmt`] implementation.
1004///
1005/// This can be constructed by the [`Formatter::debug_map`] method.
1006///
1007/// # Examples
1008///
1009/// ```
1010/// use std::fmt;
1011///
1012/// struct Foo(Vec<(String, i32)>);
1013///
1014/// impl fmt::Debug for Foo {
1015/// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1016/// fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish()
1017/// }
1018/// }
1019///
1020/// assert_eq!(
1021/// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1022/// r#"{"A": 10, "B": 11}"#,
1023/// );
1024/// ```
1025#[must_use = "must eventually call `finish()` on Debug builders"]
1026#[allow(missing_debug_implementations)]
1027#[stable(feature = "debug_builders", since = "1.2.0")]
1028pub struct DebugMap<'a, 'b: 'a> {
1029 fmt: &'a mut fmt::Formatter<'b>,
1030 result: fmt::Result,
1031 has_fields: bool,
1032 has_key: bool,
1033 // The state of newlines is tracked between keys and values
1034 state: PadAdapterState,
1035}
1036
1037pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
1038 let result = fmt.write_str("{");
1039 DebugMap { fmt, result, has_fields: false, has_key: false, state: Default::default() }
1040}
1041
1042impl<'a, 'b: 'a> DebugMap<'a, 'b> {
1043 /// Adds a new entry to the map output.
1044 ///
1045 /// # Examples
1046 ///
1047 /// ```
1048 /// use std::fmt;
1049 ///
1050 /// struct Foo(Vec<(String, i32)>);
1051 ///
1052 /// impl fmt::Debug for Foo {
1053 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1054 /// fmt.debug_map()
1055 /// .entry(&"whole", &self.0) // We add the "whole" entry.
1056 /// .finish()
1057 /// }
1058 /// }
1059 ///
1060 /// assert_eq!(
1061 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1062 /// r#"{"whole": [("A", 10), ("B", 11)]}"#,
1063 /// );
1064 /// ```
1065 #[stable(feature = "debug_builders", since = "1.2.0")]
1066 pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut Self {
1067 self.key(key).value(value)
1068 }
1069
1070 /// Adds the key part of a new entry to the map output.
1071 ///
1072 /// This method, together with `value`, is an alternative to `entry` that
1073 /// can be used when the complete entry isn't known upfront. Prefer the `entry`
1074 /// method when it's possible to use.
1075 ///
1076 /// # Panics
1077 ///
1078 /// `key` must be called before `value` and each call to `key` must be followed
1079 /// by a corresponding call to `value`. Otherwise this method will panic.
1080 ///
1081 /// # Examples
1082 ///
1083 /// ```
1084 /// use std::fmt;
1085 ///
1086 /// struct Foo(Vec<(String, i32)>);
1087 ///
1088 /// impl fmt::Debug for Foo {
1089 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1090 /// fmt.debug_map()
1091 /// .key(&"whole").value(&self.0) // We add the "whole" entry.
1092 /// .finish()
1093 /// }
1094 /// }
1095 ///
1096 /// assert_eq!(
1097 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1098 /// r#"{"whole": [("A", 10), ("B", 11)]}"#,
1099 /// );
1100 /// ```
1101 #[stable(feature = "debug_map_key_value", since = "1.42.0")]
1102 pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self {
1103 self.result = self.result.and_then(|_| {
1104 assert!(
1105 !self.has_key,
1106 "attempted to begin a new map entry \
1107 without completing the previous one"
1108 );
1109
1110 if self.is_pretty() {
1111 if !self.has_fields {
1112 self.fmt.write_str("\n")?;
1113 }
1114 let mut slot = None;
1115 self.state = Default::default();
1116 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
1117 key.fmt(&mut writer)?;
1118 writer.write_str(": ")?;
1119 } else {
1120 if self.has_fields {
1121 self.fmt.write_str(", ")?
1122 }
1123 key.fmt(self.fmt)?;
1124 self.fmt.write_str(": ")?;
1125 }
1126
1127 self.has_key = true;
1128 Ok(())
1129 });
1130
1131 self
1132 }
1133
1134 /// Adds the key part of a new entry to the map output.
1135 ///
1136 /// This method is equivalent to [`DebugMap::key`], but formats the
1137 /// key using a provided closure rather than by calling [`Debug::fmt`].
1138 ///
1139 /// # Examples
1140 ///
1141 /// ```
1142 /// #![feature(debug_closure_helpers)]
1143 ///
1144 /// use std::fmt;
1145 ///
1146 /// struct Foo(Vec<(String, i32)>);
1147 ///
1148 /// impl fmt::Debug for Foo {
1149 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1150 /// let mut map = fmt.debug_map();
1151 /// for (k, v) in &self.0 {
1152 /// // Append "entry" to each key
1153 /// map.key_with(|fmt| write!(fmt, "entry {k}"));
1154 /// // Write values as hex
1155 /// map.value_with(|fmt| write!(fmt, "{v:#010x}"));
1156 /// }
1157 /// map.finish()
1158 /// }
1159 /// }
1160 ///
1161 /// assert_eq!(
1162 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1163 /// r#"{entry A: 0x0000000a, entry B: 0x0000000b}"#,
1164 /// );
1165 /// ```
1166 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
1167 pub fn key_with<F>(&mut self, key_fmt: F) -> &mut Self
1168 where
1169 F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
1170 {
1171 self.key(&DebugOnce(Cell::new(Some(key_fmt))))
1172 }
1173
1174 /// Adds the value part of a new entry to the map output.
1175 ///
1176 /// This method, together with `key`, is an alternative to `entry` that
1177 /// can be used when the complete entry isn't known upfront. Prefer the `entry`
1178 /// method when it's possible to use.
1179 ///
1180 /// # Panics
1181 ///
1182 /// `key` must be called before `value` and each call to `key` must be followed
1183 /// by a corresponding call to `value`. Otherwise this method will panic.
1184 ///
1185 /// # Examples
1186 ///
1187 /// ```
1188 /// use std::fmt;
1189 ///
1190 /// struct Foo(Vec<(String, i32)>);
1191 ///
1192 /// impl fmt::Debug for Foo {
1193 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1194 /// fmt.debug_map()
1195 /// .key(&"whole").value(&self.0) // We add the "whole" entry.
1196 /// .finish()
1197 /// }
1198 /// }
1199 ///
1200 /// assert_eq!(
1201 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1202 /// r#"{"whole": [("A", 10), ("B", 11)]}"#,
1203 /// );
1204 /// ```
1205 #[stable(feature = "debug_map_key_value", since = "1.42.0")]
1206 pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self {
1207 self.result = self.result.and_then(|_| {
1208 assert!(self.has_key, "attempted to format a map value before its key");
1209
1210 if self.is_pretty() {
1211 let mut slot = None;
1212 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
1213 value.fmt(&mut writer)?;
1214 writer.write_str(",\n")?;
1215 } else {
1216 value.fmt(self.fmt)?;
1217 }
1218
1219 self.has_key = false;
1220 Ok(())
1221 });
1222
1223 self.has_fields = true;
1224 self
1225 }
1226
1227 /// Adds the value part of a new entry to the map output.
1228 ///
1229 /// This method is equivalent to [`DebugMap::value`], but formats the
1230 /// value using a provided closure rather than by calling [`Debug::fmt`].
1231 ///
1232 /// # Examples
1233 ///
1234 /// ```
1235 /// #![feature(debug_closure_helpers)]
1236 ///
1237 /// use std::fmt;
1238 ///
1239 /// struct Foo(Vec<(String, i32)>);
1240 ///
1241 /// impl fmt::Debug for Foo {
1242 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1243 /// let mut map = fmt.debug_map();
1244 /// for (k, v) in &self.0 {
1245 /// // Append "entry" to each key
1246 /// map.key_with(|fmt| write!(fmt, "entry {k}"));
1247 /// // Write values as hex
1248 /// map.value_with(|fmt| write!(fmt, "{v:#010x}"));
1249 /// }
1250 /// map.finish()
1251 /// }
1252 /// }
1253 ///
1254 /// assert_eq!(
1255 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1256 /// r#"{entry A: 0x0000000a, entry B: 0x0000000b}"#,
1257 /// );
1258 /// ```
1259 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
1260 pub fn value_with<F>(&mut self, value_fmt: F) -> &mut Self
1261 where
1262 F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
1263 {
1264 self.value(&DebugOnce(Cell::new(Some(value_fmt))))
1265 }
1266
1267 /// Adds the contents of an iterator of entries to the map output.
1268 ///
1269 /// # Examples
1270 ///
1271 /// ```
1272 /// use std::fmt;
1273 ///
1274 /// struct Foo(Vec<(String, i32)>);
1275 ///
1276 /// impl fmt::Debug for Foo {
1277 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1278 /// fmt.debug_map()
1279 /// // We map our vec so each entries' first field will become
1280 /// // the "key".
1281 /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
1282 /// .finish()
1283 /// }
1284 /// }
1285 ///
1286 /// assert_eq!(
1287 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1288 /// r#"{"A": 10, "B": 11}"#,
1289 /// );
1290 /// ```
1291 #[stable(feature = "debug_builders", since = "1.2.0")]
1292 pub fn entries<K, V, I>(&mut self, entries: I) -> &mut Self
1293 where
1294 K: fmt::Debug,
1295 V: fmt::Debug,
1296 I: IntoIterator<Item = (K, V)>,
1297 {
1298 for (k, v) in entries {
1299 self.entry(&k, &v);
1300 }
1301 self
1302 }
1303
1304 /// Marks the map as non-exhaustive, indicating to the reader that there are some other
1305 /// entries that are not shown in the debug representation.
1306 ///
1307 /// # Examples
1308 ///
1309 /// ```
1310 /// use std::fmt;
1311 ///
1312 /// struct Foo(Vec<(String, i32)>);
1313 ///
1314 /// impl fmt::Debug for Foo {
1315 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1316 /// // Print at most two elements, abbreviate the rest
1317 /// let mut f = fmt.debug_map();
1318 /// let mut f = f.entries(self.0.iter().take(2).map(|&(ref k, ref v)| (k, v)));
1319 /// if self.0.len() > 2 {
1320 /// f.finish_non_exhaustive()
1321 /// } else {
1322 /// f.finish()
1323 /// }
1324 /// }
1325 /// }
1326 ///
1327 /// assert_eq!(
1328 /// format!("{:?}", Foo(vec![
1329 /// ("A".to_string(), 10),
1330 /// ("B".to_string(), 11),
1331 /// ("C".to_string(), 12),
1332 /// ])),
1333 /// r#"{"A": 10, "B": 11, ..}"#,
1334 /// );
1335 /// ```
1336 #[stable(feature = "debug_more_non_exhaustive", since = "1.83.0")]
1337 pub fn finish_non_exhaustive(&mut self) -> fmt::Result {
1338 self.result = self.result.and_then(|_| {
1339 assert!(!self.has_key, "attempted to finish a map with a partial entry");
1340
1341 if self.has_fields {
1342 if self.is_pretty() {
1343 let mut slot = None;
1344 let mut state = Default::default();
1345 let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
1346 writer.write_str("..\n")?;
1347 self.fmt.write_str("}")
1348 } else {
1349 self.fmt.write_str(", ..}")
1350 }
1351 } else {
1352 self.fmt.write_str("..}")
1353 }
1354 });
1355 self.result
1356 }
1357
1358 /// Finishes output and returns any error encountered.
1359 ///
1360 /// # Panics
1361 ///
1362 /// `key` must be called before `value` and each call to `key` must be followed
1363 /// by a corresponding call to `value`. Otherwise this method will panic.
1364 ///
1365 /// # Examples
1366 ///
1367 /// ```
1368 /// use std::fmt;
1369 ///
1370 /// struct Foo(Vec<(String, i32)>);
1371 ///
1372 /// impl fmt::Debug for Foo {
1373 /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1374 /// fmt.debug_map()
1375 /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
1376 /// .finish() // Ends the map formatting.
1377 /// }
1378 /// }
1379 ///
1380 /// assert_eq!(
1381 /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
1382 /// r#"{"A": 10, "B": 11}"#,
1383 /// );
1384 /// ```
1385 #[stable(feature = "debug_builders", since = "1.2.0")]
1386 pub fn finish(&mut self) -> fmt::Result {
1387 self.result = self.result.and_then(|_| {
1388 assert!(!self.has_key, "attempted to finish a map with a partial entry");
1389
1390 self.fmt.write_str("}")
1391 });
1392 self.result
1393 }
1394
1395 fn is_pretty(&self) -> bool {
1396 self.fmt.alternate()
1397 }
1398}
1399
1400/// Creates a type whose [`fmt::Debug`] and [`fmt::Display`] impls are
1401/// forwarded to the provided closure.
1402///
1403/// # Examples
1404///
1405/// ```
1406/// use std::fmt;
1407///
1408/// let value = 'a';
1409/// assert_eq!(format!("{}", value), "a");
1410/// assert_eq!(format!("{:?}", value), "'a'");
1411///
1412/// let wrapped = fmt::from_fn(|f| write!(f, "{value:?}"));
1413/// assert_eq!(format!("{}", wrapped), "'a'");
1414/// assert_eq!(format!("{:?}", wrapped), "'a'");
1415/// ```
1416#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1417#[rustc_const_stable(feature = "const_fmt_from_fn", since = "1.95.0")]
1418#[must_use = "returns a type implementing Debug and Display, which do not have any effects unless they are used"]
1419pub const fn from_fn<F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result>(f: F) -> FromFn<F> {
1420 FromFn(f)
1421}
1422
1423/// Implements [`fmt::Debug`] and [`fmt::Display`] via the provided closure.
1424///
1425/// Created with [`from_fn`].
1426#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1427pub struct FromFn<F>(F);
1428
1429#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1430impl<F> fmt::Debug for FromFn<F>
1431where
1432 F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
1433{
1434 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1435 (self.0)(f)
1436 }
1437}
1438
1439#[stable(feature = "fmt_from_fn", since = "1.93.0")]
1440impl<F> fmt::Display for FromFn<F>
1441where
1442 F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
1443{
1444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1445 (self.0)(f)
1446 }
1447}