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