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