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