]> git.lizzy.rs Git - rust.git/blob - src/libcore/fmt/builders.rs
Auto merge of #63462 - matthewjasper:hygienic-builtin-derives, r=petrochenkov
[rust.git] / src / libcore / fmt / builders.rs
1 use crate::fmt;
2
3 struct PadAdapter<'buf, 'state> {
4     buf: &'buf mut (dyn fmt::Write + 'buf),
5     state: &'state mut PadAdapterState,
6 }
7
8 struct PadAdapterState {
9     on_newline: bool,
10 }
11
12 impl Default for PadAdapterState {
13     fn default() -> Self {
14         PadAdapterState {
15             on_newline: true,
16         }
17     }
18 }
19
20 impl<'buf, 'state> PadAdapter<'buf, 'state> {
21     fn wrap<'slot, 'fmt: 'buf+'slot>(fmt: &'fmt mut fmt::Formatter<'_>,
22                                      slot: &'slot mut Option<Self>,
23                                      state: &'state mut PadAdapterState) -> fmt::Formatter<'slot> {
24         fmt.wrap_buf(move |buf| {
25             *slot = Some(PadAdapter {
26                 buf,
27                 state,
28             });
29             slot.as_mut().unwrap()
30         })
31     }
32 }
33
34 impl fmt::Write for PadAdapter<'_, '_> {
35     fn write_str(&mut self, mut s: &str) -> fmt::Result {
36         while !s.is_empty() {
37             if self.state.on_newline {
38                 self.buf.write_str("    ")?;
39             }
40
41             let split = match s.find('\n') {
42                 Some(pos) => {
43                     self.state.on_newline = true;
44                     pos + 1
45                 }
46                 None => {
47                     self.state.on_newline = false;
48                     s.len()
49                 }
50             };
51             self.buf.write_str(&s[..split])?;
52             s = &s[split..];
53         }
54
55         Ok(())
56     }
57 }
58
59 /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations.
60 ///
61 /// This is useful when you wish to output a formatted struct as a part of your
62 /// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation.
63 ///
64 /// This can be constructed by the
65 /// [`Formatter::debug_struct`](struct.Formatter.html#method.debug_struct)
66 /// method.
67 ///
68 /// # Examples
69 ///
70 /// ```
71 /// use std::fmt;
72 ///
73 /// struct Foo {
74 ///     bar: i32,
75 ///     baz: String,
76 /// }
77 ///
78 /// impl fmt::Debug for Foo {
79 ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
80 ///         fmt.debug_struct("Foo")
81 ///            .field("bar", &self.bar)
82 ///            .field("baz", &self.baz)
83 ///            .finish()
84 ///     }
85 /// }
86 ///
87 /// assert_eq!(
88 ///     format!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }),
89 ///     "Foo { bar: 10, baz: \"Hello World\" }",
90 /// );
91 /// ```
92 #[must_use = "must eventually call `finish()` on Debug builders"]
93 #[allow(missing_debug_implementations)]
94 #[stable(feature = "debug_builders", since = "1.2.0")]
95 pub struct DebugStruct<'a, 'b: 'a> {
96     fmt: &'a mut fmt::Formatter<'b>,
97     result: fmt::Result,
98     has_fields: bool,
99 }
100
101 pub(super) fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
102                                 name: &str)
103                                 -> DebugStruct<'a, 'b> {
104     let result = fmt.write_str(name);
105     DebugStruct {
106         fmt,
107         result,
108         has_fields: false,
109     }
110 }
111
112 impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
113     /// Adds a new field to the generated struct output.
114     ///
115     /// # Examples
116     ///
117     /// ```
118     /// use std::fmt;
119     ///
120     /// struct Bar {
121     ///     bar: i32,
122     ///     another: String,
123     /// }
124     ///
125     /// impl fmt::Debug for Bar {
126     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
127     ///         fmt.debug_struct("Bar")
128     ///            .field("bar", &self.bar) // We add `bar` field.
129     ///            .field("another", &self.another) // We add `another` field.
130     ///            // We even add a field which doesn't exist (because why not?).
131     ///            .field("not_existing_field", &1)
132     ///            .finish() // We're good to go!
133     ///     }
134     /// }
135     ///
136     /// assert_eq!(
137     ///     format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
138     ///     "Bar { bar: 10, another: \"Hello World\", not_existing_field: 1 }",
139     /// );
140     /// ```
141     #[stable(feature = "debug_builders", since = "1.2.0")]
142     pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut DebugStruct<'a, 'b> {
143         self.result = self.result.and_then(|_| {
144             if self.is_pretty() {
145                 if !self.has_fields {
146                     self.fmt.write_str(" {\n")?;
147                 }
148                 let mut slot = None;
149                 let mut state = Default::default();
150                 let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state);
151                 writer.write_str(name)?;
152                 writer.write_str(": ")?;
153                 value.fmt(&mut writer)?;
154                 writer.write_str(",\n")
155             } else {
156                 let prefix = if self.has_fields { ", " } else { " { " };
157                 self.fmt.write_str(prefix)?;
158                 self.fmt.write_str(name)?;
159                 self.fmt.write_str(": ")?;
160                 value.fmt(self.fmt)
161             }
162         });
163
164         self.has_fields = true;
165         self
166     }
167
168     /// Finishes output and returns any error encountered.
169     ///
170     /// # Examples
171     ///
172     /// ```
173     /// use std::fmt;
174     ///
175     /// struct Bar {
176     ///     bar: i32,
177     ///     baz: String,
178     /// }
179     ///
180     /// impl fmt::Debug for Bar {
181     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
182     ///         fmt.debug_struct("Bar")
183     ///            .field("bar", &self.bar)
184     ///            .field("baz", &self.baz)
185     ///            .finish() // You need to call it to "finish" the
186     ///                      // struct formatting.
187     ///     }
188     /// }
189     ///
190     /// assert_eq!(
191     ///     format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }),
192     ///     "Bar { bar: 10, baz: \"Hello World\" }",
193     /// );
194     /// ```
195     #[stable(feature = "debug_builders", since = "1.2.0")]
196     pub fn finish(&mut self) -> fmt::Result {
197         if self.has_fields {
198             self.result = self.result.and_then(|_| {
199                 if self.is_pretty() {
200                     self.fmt.write_str("}")
201                 } else {
202                     self.fmt.write_str(" }")
203                 }
204             });
205         }
206         self.result
207     }
208
209     fn is_pretty(&self) -> bool {
210         self.fmt.alternate()
211     }
212 }
213
214 /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations.
215 ///
216 /// This is useful when you wish to output a formatted tuple as a part of your
217 /// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation.
218 ///
219 /// This can be constructed by the
220 /// [`Formatter::debug_tuple`](struct.Formatter.html#method.debug_tuple)
221 /// method.
222 ///
223 /// # Examples
224 ///
225 /// ```
226 /// use std::fmt;
227 ///
228 /// struct Foo(i32, String);
229 ///
230 /// impl fmt::Debug for Foo {
231 ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
232 ///         fmt.debug_tuple("Foo")
233 ///            .field(&self.0)
234 ///            .field(&self.1)
235 ///            .finish()
236 ///     }
237 /// }
238 ///
239 /// assert_eq!(
240 ///     format!("{:?}", Foo(10, "Hello World".to_string())),
241 ///     "Foo(10, \"Hello World\")",
242 /// );
243 /// ```
244 #[must_use = "must eventually call `finish()` on Debug builders"]
245 #[allow(missing_debug_implementations)]
246 #[stable(feature = "debug_builders", since = "1.2.0")]
247 pub struct DebugTuple<'a, 'b: 'a> {
248     fmt: &'a mut fmt::Formatter<'b>,
249     result: fmt::Result,
250     fields: usize,
251     empty_name: bool,
252 }
253
254 pub(super) fn debug_tuple_new<'a, 'b>(
255     fmt: &'a mut fmt::Formatter<'b>,
256     name: &str,
257 ) -> DebugTuple<'a, 'b> {
258     let result = fmt.write_str(name);
259     DebugTuple {
260         fmt,
261         result,
262         fields: 0,
263         empty_name: name.is_empty(),
264     }
265 }
266
267 impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
268     /// Adds a new field to the generated tuple struct output.
269     ///
270     /// # Examples
271     ///
272     /// ```
273     /// use std::fmt;
274     ///
275     /// struct Foo(i32, String);
276     ///
277     /// impl fmt::Debug for Foo {
278     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
279     ///         fmt.debug_tuple("Foo")
280     ///            .field(&self.0) // We add the first field.
281     ///            .field(&self.1) // We add the second field.
282     ///            .finish() // We're good to go!
283     ///     }
284     /// }
285     ///
286     /// assert_eq!(
287     ///     format!("{:?}", Foo(10, "Hello World".to_string())),
288     ///     "Foo(10, \"Hello World\")",
289     /// );
290     /// ```
291     #[stable(feature = "debug_builders", since = "1.2.0")]
292     pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut DebugTuple<'a, 'b> {
293         self.result = self.result.and_then(|_| {
294             if self.is_pretty() {
295                 if self.fields == 0 {
296                     self.fmt.write_str("(\n")?;
297                 }
298                 let mut slot = None;
299                 let mut state = Default::default();
300                 let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state);
301                 value.fmt(&mut writer)?;
302                 writer.write_str(",\n")
303             } else {
304                 let prefix = if self.fields == 0 { "(" } else { ", " };
305                 self.fmt.write_str(prefix)?;
306                 value.fmt(self.fmt)
307             }
308         });
309
310         self.fields += 1;
311         self
312     }
313
314     /// Finishes output and returns any error encountered.
315     ///
316     /// # Examples
317     ///
318     /// ```
319     /// use std::fmt;
320     ///
321     /// struct Foo(i32, String);
322     ///
323     /// impl fmt::Debug for Foo {
324     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
325     ///         fmt.debug_tuple("Foo")
326     ///            .field(&self.0)
327     ///            .field(&self.1)
328     ///            .finish() // You need to call it to "finish" the
329     ///                      // tuple formatting.
330     ///     }
331     /// }
332     ///
333     /// assert_eq!(
334     ///     format!("{:?}", Foo(10, "Hello World".to_string())),
335     ///     "Foo(10, \"Hello World\")",
336     /// );
337     /// ```
338     #[stable(feature = "debug_builders", since = "1.2.0")]
339     pub fn finish(&mut self) -> fmt::Result {
340         if self.fields > 0 {
341             self.result = self.result.and_then(|_| {
342                 if self.fields == 1 && self.empty_name && !self.is_pretty() {
343                     self.fmt.write_str(",")?;
344                 }
345                 self.fmt.write_str(")")
346             });
347         }
348         self.result
349     }
350
351     fn is_pretty(&self) -> bool {
352         self.fmt.alternate()
353     }
354 }
355
356 struct DebugInner<'a, 'b: 'a> {
357     fmt: &'a mut fmt::Formatter<'b>,
358     result: fmt::Result,
359     has_fields: bool,
360 }
361
362 impl<'a, 'b: 'a> DebugInner<'a, 'b> {
363     fn entry(&mut self, entry: &dyn fmt::Debug) {
364         self.result = self.result.and_then(|_| {
365             if self.is_pretty() {
366                 if !self.has_fields {
367                     self.fmt.write_str("\n")?;
368                 }
369                 let mut slot = None;
370                 let mut state = Default::default();
371                 let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state);
372                 entry.fmt(&mut writer)?;
373                 writer.write_str(",\n")
374             } else {
375                 if self.has_fields {
376                     self.fmt.write_str(", ")?
377                 }
378                 entry.fmt(self.fmt)
379             }
380         });
381
382         self.has_fields = true;
383     }
384
385     fn is_pretty(&self) -> bool {
386         self.fmt.alternate()
387     }
388 }
389
390 /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations.
391 ///
392 /// This is useful when you wish to output a formatted set of items as a part
393 /// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation.
394 ///
395 /// This can be constructed by the
396 /// [`Formatter::debug_set`](struct.Formatter.html#method.debug_set)
397 /// method.
398 ///
399 /// # Examples
400 ///
401 /// ```
402 /// use std::fmt;
403 ///
404 /// struct Foo(Vec<i32>);
405 ///
406 /// impl fmt::Debug for Foo {
407 ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
408 ///         fmt.debug_set().entries(self.0.iter()).finish()
409 ///     }
410 /// }
411 ///
412 /// assert_eq!(
413 ///     format!("{:?}", Foo(vec![10, 11])),
414 ///     "{10, 11}",
415 /// );
416 /// ```
417 #[must_use = "must eventually call `finish()` on Debug builders"]
418 #[allow(missing_debug_implementations)]
419 #[stable(feature = "debug_builders", since = "1.2.0")]
420 pub struct DebugSet<'a, 'b: 'a> {
421     inner: DebugInner<'a, 'b>,
422 }
423
424 pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
425     let result = fmt.write_str("{");
426     DebugSet {
427         inner: DebugInner {
428             fmt,
429             result,
430             has_fields: false,
431         },
432     }
433 }
434
435 impl<'a, 'b: 'a> DebugSet<'a, 'b> {
436     /// Adds a new entry to the set output.
437     ///
438     /// # Examples
439     ///
440     /// ```
441     /// use std::fmt;
442     ///
443     /// struct Foo(Vec<i32>, Vec<u32>);
444     ///
445     /// impl fmt::Debug for Foo {
446     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
447     ///         fmt.debug_set()
448     ///            .entry(&self.0) // Adds the first "entry".
449     ///            .entry(&self.1) // Adds the second "entry".
450     ///            .finish()
451     ///     }
452     /// }
453     ///
454     /// assert_eq!(
455     ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
456     ///     "{[10, 11], [12, 13]}",
457     /// );
458     /// ```
459     #[stable(feature = "debug_builders", since = "1.2.0")]
460     pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugSet<'a, 'b> {
461         self.inner.entry(entry);
462         self
463     }
464
465     /// Adds the contents of an iterator of entries to the set output.
466     ///
467     /// # Examples
468     ///
469     /// ```
470     /// use std::fmt;
471     ///
472     /// struct Foo(Vec<i32>, Vec<u32>);
473     ///
474     /// impl fmt::Debug for Foo {
475     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
476     ///         fmt.debug_set()
477     ///            .entries(self.0.iter()) // Adds the first "entry".
478     ///            .entries(self.1.iter()) // Adds the second "entry".
479     ///            .finish()
480     ///     }
481     /// }
482     ///
483     /// assert_eq!(
484     ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
485     ///     "{10, 11, 12, 13}",
486     /// );
487     /// ```
488     #[stable(feature = "debug_builders", since = "1.2.0")]
489     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugSet<'a, 'b>
490         where D: fmt::Debug,
491               I: IntoIterator<Item = D>
492     {
493         for entry in entries {
494             self.entry(&entry);
495         }
496         self
497     }
498
499     /// Finishes output and returns any error encountered.
500     ///
501     /// # Examples
502     ///
503     /// ```
504     /// use std::fmt;
505     ///
506     /// struct Foo(Vec<i32>);
507     ///
508     /// impl fmt::Debug for Foo {
509     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
510     ///         fmt.debug_set()
511     ///            .entries(self.0.iter())
512     ///            .finish() // Ends the struct formatting.
513     ///     }
514     /// }
515     ///
516     /// assert_eq!(
517     ///     format!("{:?}", Foo(vec![10, 11])),
518     ///     "{10, 11}",
519     /// );
520     /// ```
521     #[stable(feature = "debug_builders", since = "1.2.0")]
522     pub fn finish(&mut self) -> fmt::Result {
523         self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
524     }
525 }
526
527 /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations.
528 ///
529 /// This is useful when you wish to output a formatted list of items as a part
530 /// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation.
531 ///
532 /// This can be constructed by the
533 /// [`Formatter::debug_list`](struct.Formatter.html#method.debug_list)
534 /// method.
535 ///
536 /// # Examples
537 ///
538 /// ```
539 /// use std::fmt;
540 ///
541 /// struct Foo(Vec<i32>);
542 ///
543 /// impl fmt::Debug for Foo {
544 ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
545 ///         fmt.debug_list().entries(self.0.iter()).finish()
546 ///     }
547 /// }
548 ///
549 /// assert_eq!(
550 ///     format!("{:?}", Foo(vec![10, 11])),
551 ///     "[10, 11]",
552 /// );
553 /// ```
554 #[must_use = "must eventually call `finish()` on Debug builders"]
555 #[allow(missing_debug_implementations)]
556 #[stable(feature = "debug_builders", since = "1.2.0")]
557 pub struct DebugList<'a, 'b: 'a> {
558     inner: DebugInner<'a, 'b>,
559 }
560
561 pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
562     let result = fmt.write_str("[");
563     DebugList {
564         inner: DebugInner {
565             fmt,
566             result,
567             has_fields: false,
568         },
569     }
570 }
571
572 impl<'a, 'b: 'a> DebugList<'a, 'b> {
573     /// Adds a new entry to the list output.
574     ///
575     /// # Examples
576     ///
577     /// ```
578     /// use std::fmt;
579     ///
580     /// struct Foo(Vec<i32>, Vec<u32>);
581     ///
582     /// impl fmt::Debug for Foo {
583     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
584     ///         fmt.debug_list()
585     ///            .entry(&self.0) // We add the first "entry".
586     ///            .entry(&self.1) // We add the second "entry".
587     ///            .finish()
588     ///     }
589     /// }
590     ///
591     /// assert_eq!(
592     ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
593     ///     "[[10, 11], [12, 13]]",
594     /// );
595     /// ```
596     #[stable(feature = "debug_builders", since = "1.2.0")]
597     pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugList<'a, 'b> {
598         self.inner.entry(entry);
599         self
600     }
601
602     /// Adds the contents of an iterator of entries to the list output.
603     ///
604     /// # Examples
605     ///
606     /// ```
607     /// use std::fmt;
608     ///
609     /// struct Foo(Vec<i32>, Vec<u32>);
610     ///
611     /// impl fmt::Debug for Foo {
612     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
613     ///         fmt.debug_list()
614     ///            .entries(self.0.iter())
615     ///            .entries(self.1.iter())
616     ///            .finish()
617     ///     }
618     /// }
619     ///
620     /// assert_eq!(
621     ///     format!("{:?}", Foo(vec![10, 11], vec![12, 13])),
622     ///     "[10, 11, 12, 13]",
623     /// );
624     /// ```
625     #[stable(feature = "debug_builders", since = "1.2.0")]
626     pub fn entries<D, I>(&mut self, entries: I) -> &mut DebugList<'a, 'b>
627         where D: fmt::Debug,
628               I: IntoIterator<Item = D>
629     {
630         for entry in entries {
631             self.entry(&entry);
632         }
633         self
634     }
635
636     /// Finishes output and returns any error encountered.
637     ///
638     /// # Examples
639     ///
640     /// ```
641     /// use std::fmt;
642     ///
643     /// struct Foo(Vec<i32>);
644     ///
645     /// impl fmt::Debug for Foo {
646     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
647     ///         fmt.debug_list()
648     ///            .entries(self.0.iter())
649     ///            .finish() // Ends the struct formatting.
650     ///     }
651     /// }
652     ///
653     /// assert_eq!(
654     ///     format!("{:?}", Foo(vec![10, 11])),
655     ///     "[10, 11]",
656     /// );
657     /// ```
658     #[stable(feature = "debug_builders", since = "1.2.0")]
659     pub fn finish(&mut self) -> fmt::Result {
660         self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
661     }
662 }
663
664 /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations.
665 ///
666 /// This is useful when you wish to output a formatted map as a part of your
667 /// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation.
668 ///
669 /// This can be constructed by the
670 /// [`Formatter::debug_map`](struct.Formatter.html#method.debug_map)
671 /// method.
672 ///
673 /// # Examples
674 ///
675 /// ```
676 /// use std::fmt;
677 ///
678 /// struct Foo(Vec<(String, i32)>);
679 ///
680 /// impl fmt::Debug for Foo {
681 ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
682 ///         fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish()
683 ///     }
684 /// }
685 ///
686 /// assert_eq!(
687 ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
688 ///     "{\"A\": 10, \"B\": 11}",
689 /// );
690 /// ```
691 #[must_use = "must eventually call `finish()` on Debug builders"]
692 #[allow(missing_debug_implementations)]
693 #[stable(feature = "debug_builders", since = "1.2.0")]
694 pub struct DebugMap<'a, 'b: 'a> {
695     fmt: &'a mut fmt::Formatter<'b>,
696     result: fmt::Result,
697     has_fields: bool,
698     has_key: bool,
699     // The state of newlines is tracked between keys and values
700     state: PadAdapterState,
701 }
702
703 pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
704     let result = fmt.write_str("{");
705     DebugMap {
706         fmt,
707         result,
708         has_fields: false,
709         has_key: false,
710         state: Default::default(),
711     }
712 }
713
714 impl<'a, 'b: 'a> DebugMap<'a, 'b> {
715     /// Adds a new entry to the map output.
716     ///
717     /// # Examples
718     ///
719     /// ```
720     /// use std::fmt;
721     ///
722     /// struct Foo(Vec<(String, i32)>);
723     ///
724     /// impl fmt::Debug for Foo {
725     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
726     ///         fmt.debug_map()
727     ///            .entry(&"whole", &self.0) // We add the "whole" entry.
728     ///            .finish()
729     ///     }
730     /// }
731     ///
732     /// assert_eq!(
733     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
734     ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
735     /// );
736     /// ```
737     #[stable(feature = "debug_builders", since = "1.2.0")]
738     pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
739         self.key(key).value(value)
740     }
741
742     /// Adds the key part of a new entry to the map output.
743     ///
744     /// This method, together with `value`, is an alternative to `entry` that
745     /// can be used when the complete entry isn't known upfront. Prefer the `entry`
746     /// method when it's possible to use.
747     ///
748     /// # Panics
749     ///
750     /// `key` must be called before `value` and each call to `key` must be followed
751     /// by a corresponding call to `value`. Otherwise this method will panic.
752     ///
753     /// # Examples
754     ///
755     /// ```
756     /// # #![feature(debug_map_key_value)]
757     /// use std::fmt;
758     ///
759     /// struct Foo(Vec<(String, i32)>);
760     ///
761     /// impl fmt::Debug for Foo {
762     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
763     ///         fmt.debug_map()
764     ///            .key(&"whole").value(&self.0) // We add the "whole" entry.
765     ///            .finish()
766     ///     }
767     /// }
768     ///
769     /// assert_eq!(
770     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
771     ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
772     /// );
773     /// ```
774     #[unstable(feature = "debug_map_key_value",
775                reason = "recently added",
776                issue = "62482")]
777     pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
778         assert!(!self.has_key, "attempted to begin a new map entry \
779                                 without completing the previous one");
780
781         self.result = self.result.and_then(|_| {
782             if self.is_pretty() {
783                 if !self.has_fields {
784                     self.fmt.write_str("\n")?;
785                 }
786                 let mut slot = None;
787                 self.state = Default::default();
788                 let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state);
789                 key.fmt(&mut writer)?;
790                 writer.write_str(": ")?;
791             } else {
792                 if self.has_fields {
793                     self.fmt.write_str(", ")?
794                 }
795                 key.fmt(self.fmt)?;
796                 self.fmt.write_str(": ")?;
797             }
798
799             self.has_key = true;
800             Ok(())
801         });
802
803         self
804     }
805
806     /// Adds the value part of a new entry to the map output.
807     ///
808     /// This method, together with `key`, is an alternative to `entry` that
809     /// can be used when the complete entry isn't known upfront. Prefer the `entry`
810     /// method when it's possible to use.
811     ///
812     /// # Panics
813     ///
814     /// `key` must be called before `value` and each call to `key` must be followed
815     /// by a corresponding call to `value`. Otherwise this method will panic.
816     ///
817     /// # Examples
818     ///
819     /// ```
820     /// # #![feature(debug_map_key_value)]
821     /// use std::fmt;
822     ///
823     /// struct Foo(Vec<(String, i32)>);
824     ///
825     /// impl fmt::Debug for Foo {
826     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
827     ///         fmt.debug_map()
828     ///            .key(&"whole").value(&self.0) // We add the "whole" entry.
829     ///            .finish()
830     ///     }
831     /// }
832     ///
833     /// assert_eq!(
834     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
835     ///     "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
836     /// );
837     /// ```
838     #[unstable(feature = "debug_map_key_value",
839                reason = "recently added",
840                issue = "62482")]
841     pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
842         assert!(self.has_key, "attempted to format a map value before its key");
843
844         self.result = self.result.and_then(|_| {
845             if self.is_pretty() {
846                 let mut slot = None;
847                 let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state);
848                 value.fmt(&mut writer)?;
849                 writer.write_str(",\n")?;
850             } else {
851                 value.fmt(self.fmt)?;
852             }
853
854             self.has_key = false;
855             Ok(())
856         });
857
858         self.has_fields = true;
859         self
860     }
861
862     /// Adds the contents of an iterator of entries to the map output.
863     ///
864     /// # Examples
865     ///
866     /// ```
867     /// use std::fmt;
868     ///
869     /// struct Foo(Vec<(String, i32)>);
870     ///
871     /// impl fmt::Debug for Foo {
872     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
873     ///         fmt.debug_map()
874     ///            // We map our vec so each entries' first field will become
875     ///            // the "key".
876     ///            .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
877     ///            .finish()
878     ///     }
879     /// }
880     ///
881     /// assert_eq!(
882     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
883     ///     "{\"A\": 10, \"B\": 11}",
884     /// );
885     /// ```
886     #[stable(feature = "debug_builders", since = "1.2.0")]
887     pub fn entries<K, V, I>(&mut self, entries: I) -> &mut DebugMap<'a, 'b>
888         where K: fmt::Debug,
889               V: fmt::Debug,
890               I: IntoIterator<Item = (K, V)>
891     {
892         for (k, v) in entries {
893             self.entry(&k, &v);
894         }
895         self
896     }
897
898     /// Finishes output and returns any error encountered.
899     ///
900     /// # Panics
901     ///
902     /// `key` must be called before `value` and each call to `key` must be followed
903     /// by a corresponding call to `value`. Otherwise this method will panic.
904     ///
905     /// # Examples
906     ///
907     /// ```
908     /// use std::fmt;
909     ///
910     /// struct Foo(Vec<(String, i32)>);
911     ///
912     /// impl fmt::Debug for Foo {
913     ///     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
914     ///         fmt.debug_map()
915     ///            .entries(self.0.iter().map(|&(ref k, ref v)| (k, v)))
916     ///            .finish() // Ends the struct formatting.
917     ///     }
918     /// }
919     ///
920     /// assert_eq!(
921     ///     format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
922     ///     "{\"A\": 10, \"B\": 11}",
923     /// );
924     /// ```
925     #[stable(feature = "debug_builders", since = "1.2.0")]
926     pub fn finish(&mut self) -> fmt::Result {
927         assert!(!self.has_key, "attempted to finish a map with a partial entry");
928
929         self.result.and_then(|_| self.fmt.write_str("}"))
930     }
931
932     fn is_pretty(&self) -> bool {
933         self.fmt.alternate()
934     }
935 }