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