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