use crate::fmt; struct PadAdapter<'buf, 'state> { buf: &'buf mut (dyn fmt::Write + 'buf), state: &'state mut PadAdapterState, } struct PadAdapterState { on_newline: bool, } impl Default for PadAdapterState { fn default() -> Self { PadAdapterState { on_newline: true } } } impl<'buf, 'state> PadAdapter<'buf, 'state> { fn wrap<'slot, 'fmt: 'buf + 'slot>( fmt: &'fmt mut fmt::Formatter<'_>, slot: &'slot mut Option, state: &'state mut PadAdapterState, ) -> fmt::Formatter<'slot> { fmt.wrap_buf(move |buf| { *slot = Some(PadAdapter { buf, state }); slot.as_mut().unwrap() }) } } impl fmt::Write for PadAdapter<'_, '_> { fn write_str(&mut self, mut s: &str) -> fmt::Result { while !s.is_empty() { if self.state.on_newline { self.buf.write_str(" ")?; } let split = match s.find('\n') { Some(pos) => { self.state.on_newline = true; pos + 1 } None => { self.state.on_newline = false; s.len() } }; self.buf.write_str(&s[..split])?; s = &s[split..]; } Ok(()) } } /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. /// /// This is useful when you wish to output a formatted struct as a part of your /// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. /// /// This can be constructed by the /// [`Formatter::debug_struct`](struct.Formatter.html#method.debug_struct) /// method. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo { /// bar: i32, /// baz: String, /// } /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// fmt.debug_struct("Foo") /// .field("bar", &self.bar) /// .field("baz", &self.baz) /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }), /// "Foo { bar: 10, baz: \"Hello World\" }", /// ); /// ``` #[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugStruct<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, has_fields: bool, } pub(super) fn debug_struct_new<'a, 'b>( fmt: &'a mut fmt::Formatter<'b>, name: &str, ) -> DebugStruct<'a, 'b> { let result = fmt.write_str(name); DebugStruct { fmt, result, has_fields: false } } impl<'a, 'b: 'a> DebugStruct<'a, 'b> { /// Adds a new field to the generated struct output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Bar { /// bar: i32, /// another: String, /// } /// /// impl fmt::Debug for Bar { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_struct("Bar") /// .field("bar", &self.bar) // We add `bar` field. /// .field("another", &self.another) // We add `another` field. /// // We even add a field which doesn't exist (because why not?). /// .field("not_existing_field", &1) /// .finish() // We're good to go! /// } /// } /// /// assert_eq!( /// format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }), /// "Bar { bar: 10, another: \"Hello World\", not_existing_field: 1 }", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut DebugStruct<'a, 'b> { self.result = self.result.and_then(|_| { if self.is_pretty() { if !self.has_fields { self.fmt.write_str(" {\n")?; } let mut slot = None; let mut state = Default::default(); let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); writer.write_str(name)?; writer.write_str(": ")?; value.fmt(&mut writer)?; writer.write_str(",\n") } else { let prefix = if self.has_fields { ", " } else { " { " }; self.fmt.write_str(prefix)?; self.fmt.write_str(name)?; self.fmt.write_str(": ")?; value.fmt(self.fmt) } }); self.has_fields = true; self } /// Finishes output and returns any error encountered. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Bar { /// bar: i32, /// baz: String, /// } /// /// impl fmt::Debug for Bar { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_struct("Bar") /// .field("bar", &self.bar) /// .field("baz", &self.baz) /// .finish() // You need to call it to "finish" the /// // struct formatting. /// } /// } /// /// assert_eq!( /// format!("{:?}", Bar { bar: 10, baz: "Hello World".to_string() }), /// "Bar { bar: 10, baz: \"Hello World\" }", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn finish(&mut self) -> fmt::Result { if self.has_fields { self.result = self.result.and_then(|_| { if self.is_pretty() { self.fmt.write_str("}") } else { self.fmt.write_str(" }") } }); } self.result } fn is_pretty(&self) -> bool { self.fmt.alternate() } } /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. /// /// This is useful when you wish to output a formatted tuple as a part of your /// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. /// /// This can be constructed by the /// [`Formatter::debug_tuple`](struct.Formatter.html#method.debug_tuple) /// method. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(i32, String); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// fmt.debug_tuple("Foo") /// .field(&self.0) /// .field(&self.1) /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(10, "Hello World".to_string())), /// "Foo(10, \"Hello World\")", /// ); /// ``` #[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugTuple<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, fields: usize, empty_name: bool, } pub(super) fn debug_tuple_new<'a, 'b>( fmt: &'a mut fmt::Formatter<'b>, name: &str, ) -> DebugTuple<'a, 'b> { let result = fmt.write_str(name); DebugTuple { fmt, result, fields: 0, empty_name: name.is_empty() } } impl<'a, 'b: 'a> DebugTuple<'a, 'b> { /// Adds a new field to the generated tuple struct output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(i32, String); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_tuple("Foo") /// .field(&self.0) // We add the first field. /// .field(&self.1) // We add the second field. /// .finish() // We're good to go! /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(10, "Hello World".to_string())), /// "Foo(10, \"Hello World\")", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut DebugTuple<'a, 'b> { self.result = self.result.and_then(|_| { if self.is_pretty() { if self.fields == 0 { self.fmt.write_str("(\n")?; } let mut slot = None; let mut state = Default::default(); let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); value.fmt(&mut writer)?; writer.write_str(",\n") } else { let prefix = if self.fields == 0 { "(" } else { ", " }; self.fmt.write_str(prefix)?; value.fmt(self.fmt) } }); self.fields += 1; self } /// Finishes output and returns any error encountered. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(i32, String); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_tuple("Foo") /// .field(&self.0) /// .field(&self.1) /// .finish() // You need to call it to "finish" the /// // tuple formatting. /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(10, "Hello World".to_string())), /// "Foo(10, \"Hello World\")", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn finish(&mut self) -> fmt::Result { if self.fields > 0 { self.result = self.result.and_then(|_| { if self.fields == 1 && self.empty_name && !self.is_pretty() { self.fmt.write_str(",")?; } self.fmt.write_str(")") }); } self.result } fn is_pretty(&self) -> bool { self.fmt.alternate() } } struct DebugInner<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, has_fields: bool, } impl<'a, 'b: 'a> DebugInner<'a, 'b> { fn entry(&mut self, entry: &dyn fmt::Debug) { self.result = self.result.and_then(|_| { if self.is_pretty() { if !self.has_fields { self.fmt.write_str("\n")?; } let mut slot = None; let mut state = Default::default(); let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); entry.fmt(&mut writer)?; writer.write_str(",\n") } else { if self.has_fields { self.fmt.write_str(", ")? } entry.fmt(self.fmt) } }); self.has_fields = true; } fn is_pretty(&self) -> bool { self.fmt.alternate() } } /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. /// /// This is useful when you wish to output a formatted set of items as a part /// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. /// /// This can be constructed by the /// [`Formatter::debug_set`](struct.Formatter.html#method.debug_set) /// method. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// fmt.debug_set().entries(self.0.iter()).finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11])), /// "{10, 11}", /// ); /// ``` #[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugSet<'a, 'b: 'a> { inner: DebugInner<'a, 'b>, } pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> { let result = fmt.write_str("{"); DebugSet { inner: DebugInner { fmt, result, has_fields: false } } } impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// Adds a new entry to the set output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec, Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_set() /// .entry(&self.0) // Adds the first "entry". /// .entry(&self.1) // Adds the second "entry". /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])), /// "{[10, 11], [12, 13]}", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugSet<'a, 'b> { self.inner.entry(entry); self } /// Adds the contents of an iterator of entries to the set output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec, Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_set() /// .entries(self.0.iter()) // Adds the first "entry". /// .entries(self.1.iter()) // Adds the second "entry". /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])), /// "{10, 11, 12, 13}", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entries(&mut self, entries: I) -> &mut DebugSet<'a, 'b> where D: fmt::Debug, I: IntoIterator, { for entry in entries { self.entry(&entry); } self } /// Finishes output and returns any error encountered. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_set() /// .entries(self.0.iter()) /// .finish() // Ends the struct formatting. /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11])), /// "{10, 11}", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn finish(&mut self) -> fmt::Result { self.inner.result.and_then(|_| self.inner.fmt.write_str("}")) } } /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. /// /// This is useful when you wish to output a formatted list of items as a part /// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. /// /// This can be constructed by the /// [`Formatter::debug_list`](struct.Formatter.html#method.debug_list) /// method. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// fmt.debug_list().entries(self.0.iter()).finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11])), /// "[10, 11]", /// ); /// ``` #[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugList<'a, 'b: 'a> { inner: DebugInner<'a, 'b>, } pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> { let result = fmt.write_str("["); DebugList { inner: DebugInner { fmt, result, has_fields: false } } } impl<'a, 'b: 'a> DebugList<'a, 'b> { /// Adds a new entry to the list output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec, Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_list() /// .entry(&self.0) // We add the first "entry". /// .entry(&self.1) // We add the second "entry". /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])), /// "[[10, 11], [12, 13]]", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugList<'a, 'b> { self.inner.entry(entry); self } /// Adds the contents of an iterator of entries to the list output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec, Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_list() /// .entries(self.0.iter()) /// .entries(self.1.iter()) /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11], vec![12, 13])), /// "[10, 11, 12, 13]", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entries(&mut self, entries: I) -> &mut DebugList<'a, 'b> where D: fmt::Debug, I: IntoIterator, { for entry in entries { self.entry(&entry); } self } /// Finishes output and returns any error encountered. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_list() /// .entries(self.0.iter()) /// .finish() // Ends the struct formatting. /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![10, 11])), /// "[10, 11]", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn finish(&mut self) -> fmt::Result { self.inner.result.and_then(|_| self.inner.fmt.write_str("]")) } } /// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. /// /// This is useful when you wish to output a formatted map as a part of your /// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. /// /// This can be constructed by the /// [`Formatter::debug_map`](struct.Formatter.html#method.debug_map) /// method. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec<(String, i32)>); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// fmt.debug_map().entries(self.0.iter().map(|&(ref k, ref v)| (k, v))).finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), /// "{\"A\": 10, \"B\": 11}", /// ); /// ``` #[must_use = "must eventually call `finish()` on Debug builders"] #[allow(missing_debug_implementations)] #[stable(feature = "debug_builders", since = "1.2.0")] pub struct DebugMap<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, has_fields: bool, has_key: bool, // The state of newlines is tracked between keys and values state: PadAdapterState, } pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { let result = fmt.write_str("{"); DebugMap { fmt, result, has_fields: false, has_key: false, state: Default::default() } } impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// Adds a new entry to the map output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec<(String, i32)>); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_map() /// .entry(&"whole", &self.0) // We add the "whole" entry. /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { self.key(key).value(value) } /// Adds the key part of a new entry to the map output. /// /// This method, together with `value`, is an alternative to `entry` that /// can be used when the complete entry isn't known upfront. Prefer the `entry` /// method when it's possible to use. /// /// # Panics /// /// `key` must be called before `value` and each call to `key` must be followed /// by a corresponding call to `value`. Otherwise this method will panic. /// /// # Examples /// /// ``` /// # #![feature(debug_map_key_value)] /// use std::fmt; /// /// struct Foo(Vec<(String, i32)>); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_map() /// .key(&"whole").value(&self.0) // We add the "whole" entry. /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}", /// ); /// ``` #[unstable(feature = "debug_map_key_value", reason = "recently added", issue = "62482")] pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { self.result = self.result.and_then(|_| { assert!( !self.has_key, "attempted to begin a new map entry \ without completing the previous one" ); if self.is_pretty() { if !self.has_fields { self.fmt.write_str("\n")?; } let mut slot = None; self.state = Default::default(); let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state); key.fmt(&mut writer)?; writer.write_str(": ")?; } else { if self.has_fields { self.fmt.write_str(", ")? } key.fmt(self.fmt)?; self.fmt.write_str(": ")?; } self.has_key = true; Ok(()) }); self } /// Adds the value part of a new entry to the map output. /// /// This method, together with `key`, is an alternative to `entry` that /// can be used when the complete entry isn't known upfront. Prefer the `entry` /// method when it's possible to use. /// /// # Panics /// /// `key` must be called before `value` and each call to `key` must be followed /// by a corresponding call to `value`. Otherwise this method will panic. /// /// # Examples /// /// ``` /// # #![feature(debug_map_key_value)] /// use std::fmt; /// /// struct Foo(Vec<(String, i32)>); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_map() /// .key(&"whole").value(&self.0) // We add the "whole" entry. /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}", /// ); /// ``` #[unstable(feature = "debug_map_key_value", reason = "recently added", issue = "62482")] pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { self.result = self.result.and_then(|_| { assert!(self.has_key, "attempted to format a map value before its key"); if self.is_pretty() { let mut slot = None; let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut self.state); value.fmt(&mut writer)?; writer.write_str(",\n")?; } else { value.fmt(self.fmt)?; } self.has_key = false; Ok(()) }); self.has_fields = true; self } /// Adds the contents of an iterator of entries to the map output. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec<(String, i32)>); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_map() /// // We map our vec so each entries' first field will become /// // the "key". /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v))) /// .finish() /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), /// "{\"A\": 10, \"B\": 11}", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn entries(&mut self, entries: I) -> &mut DebugMap<'a, 'b> where K: fmt::Debug, V: fmt::Debug, I: IntoIterator, { for (k, v) in entries { self.entry(&k, &v); } self } /// Finishes output and returns any error encountered. /// /// # Panics /// /// `key` must be called before `value` and each call to `key` must be followed /// by a corresponding call to `value`. Otherwise this method will panic. /// /// # Examples /// /// ``` /// use std::fmt; /// /// struct Foo(Vec<(String, i32)>); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// fmt.debug_map() /// .entries(self.0.iter().map(|&(ref k, ref v)| (k, v))) /// .finish() // Ends the struct formatting. /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])), /// "{\"A\": 10, \"B\": 11}", /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn finish(&mut self) -> fmt::Result { self.result.and_then(|_| { assert!(!self.has_key, "attempted to finish a map with a partial entry"); self.fmt.write_str("}") }) } fn is_pretty(&self) -> bool { self.fmt.alternate() } }