From 4037f2a368edd75c561bc6f3d8c6f0d644bc4180 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 26 Mar 2015 22:42:29 -0700 Subject: [PATCH 1/4] Update debug helpers and add list builder The collections debug helpers no longer prefix output with the collection name, in line with the current conventions for Debug implementations. Implementations that want to preserve the current behavior can simply add a `try!(write!(fmt, "TypeName "));` at the beginning of the `fmt` method. [breaking-change] --- src/libcollections/btree/map.rs | 11 +- src/libcollections/btree/set.rs | 11 +- src/libcollections/lib.rs | 1 + src/libcollections/linked_list.rs | 11 +- src/libcore/fmt/builders.rs | 142 ++++++++++++++++---------- src/libcore/fmt/mod.rs | 52 ++++++++-- src/libcoretest/fmt/builders.rs | 157 +++++++++++++++++++++++------ src/libstd/collections/hash/map.rs | 11 +- src/libstd/collections/hash/set.rs | 11 +- src/libstd/lib.rs | 1 + 10 files changed, 277 insertions(+), 131 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index d2b45f4b049..93978e31de5 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -904,14 +904,11 @@ impl Ord for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}: {:?}", *k, *v)); + let mut builder = f.debug_map(); + for (k, v) in self { + builder = builder.entry(k, v); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 08ee5801482..db0cdd30b1b 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -628,14 +628,11 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeSet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, x) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}", *x)); + let mut builder = f.debug_set(); + for x in self { + builder = builder.entry(x); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index f774c1505b8..c769b3df37f 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -40,6 +40,7 @@ #![feature(str_char)] #![feature(convert)] #![feature(slice_patterns)] +#![feature(debug_builders)] #![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))] #![cfg_attr(test, allow(deprecated))] // rand diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 908c78a17f4..56c880ca6e2 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -927,14 +927,11 @@ impl Clone for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "[")); - - for (i, e) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}", *e)); + let mut builder = f.debug_list(); + for e in self { + builder = builder.entry(e); } - - write!(f, "]") + builder.finish() } } diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index 07f029cc15e..f61a7f2d30c 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -177,22 +177,54 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> { } } -/// A struct to help with `fmt::Debug` implementations. -/// -/// Constructed by the `Formatter::debug_set` method. -#[must_use] -pub struct DebugSet<'a, 'b: 'a> { +struct DebugInner<'a, 'b: 'a> { fmt: &'a mut fmt::Formatter<'b>, result: fmt::Result, has_fields: bool, } -pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugSet<'a, 'b> { - let result = write!(fmt, "{} {{", name); +impl<'a, 'b: 'a> DebugInner<'a, 'b> { + fn entry(&mut self, entry: &fmt::Debug) { + self.result = self.result.and_then(|_| { + if self.is_pretty() { + let mut writer = PadAdapter::new(self.fmt); + let prefix = if self.has_fields { "," } else { "" }; + fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry)) + } else { + let prefix = if self.has_fields { ", " } else { "" }; + write!(self.fmt, "{}{:?}", prefix, entry) + } + }); + + self.has_fields = true; + } + + pub fn finish(&mut self) { + let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" }; + self.result = self.result.and_then(|_| self.fmt.write_str(prefix)); + } + + fn is_pretty(&self) -> bool { + self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_set` method. +#[must_use] +pub struct DebugSet<'a, 'b: 'a> { + inner: DebugInner<'a, 'b>, +} + +pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> { + let result = write!(fmt, "{{"); DebugSet { - fmt: fmt, - result: result, - has_fields: false, + inner: DebugInner { + fmt: fmt, + result: result, + has_fields: false, + } } } @@ -200,41 +232,52 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// Adds a new entry to the set output. #[unstable(feature = "debug_builders", reason = "method was just created")] pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> { - self.result = self.result.and_then(|_| { - let prefix = if self.has_fields { - "," - } else { - "" - }; - - if self.is_pretty() { - let mut writer = PadAdapter::new(self.fmt); - fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry)) - } else { - write!(self.fmt, "{} {:?}", prefix, entry) - } - }); - - self.has_fields = true; + self.inner.entry(entry); self } /// Consumes the `DebugSet`, finishing output and returning any error /// encountered. #[unstable(feature = "debug_builders", reason = "method was just created")] - pub fn finish(self) -> fmt::Result { - self.result.and_then(|_| { - let end = match (self.has_fields, self.is_pretty()) { - (false, _) => "}", - (true, false) => " }", - (true, true) => "\n}", - }; - self.fmt.write_str(end) - }) + pub fn finish(mut self) -> fmt::Result { + self.inner.finish(); + self.inner.result.and_then(|_| self.inner.fmt.write_str("}")) + } +} + +/// A struct to help with `fmt::Debug` implementations. +/// +/// Constructed by the `Formatter::debug_list` method. +#[must_use] +pub struct DebugList<'a, 'b: 'a> { + inner: DebugInner<'a, 'b>, +} + +pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> { + let result = write!(fmt, "["); + DebugList { + inner: DebugInner { + fmt: fmt, + result: result, + has_fields: false, + } + } +} + +impl<'a, 'b: 'a> DebugList<'a, 'b> { + /// Adds a new entry to the set output. + #[unstable(feature = "debug_builders", reason = "method was just created")] + pub fn entry(mut self, entry: &fmt::Debug) -> DebugList<'a, 'b> { + self.inner.entry(entry); + self } - fn is_pretty(&self) -> bool { - self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0 + /// Consumes the `DebugSet`, finishing output and returning any error + /// encountered. + #[unstable(feature = "debug_builders", reason = "method was just created")] + pub fn finish(mut self) -> fmt::Result { + self.inner.finish(); + self.inner.result.and_then(|_| self.inner.fmt.write_str("]")) } } @@ -248,8 +291,8 @@ pub struct DebugMap<'a, 'b: 'a> { has_fields: bool, } -pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugMap<'a, 'b> { - let result = write!(fmt, "{} {{", name); +pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> { + let result = write!(fmt, "{{"); DebugMap { fmt: fmt, result: result, @@ -262,22 +305,17 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { #[unstable(feature = "debug_builders", reason = "method was just created")] pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> { self.result = self.result.and_then(|_| { - let prefix = if self.has_fields { - "," - } else { - "" - }; - if self.is_pretty() { let mut writer = PadAdapter::new(self.fmt); + let prefix = if self.has_fields { "," } else { "" }; fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value)) } else { - write!(self.fmt, "{} {:?}: {:?}", prefix, key, value) + let prefix = if self.has_fields { ", " } else { "" }; + write!(self.fmt, "{}{:?}: {:?}", prefix, key, value) } }); self.has_fields = true; - self } @@ -285,14 +323,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// encountered. #[unstable(feature = "debug_builders", reason = "method was just created")] pub fn finish(self) -> fmt::Result { - self.result.and_then(|_| { - let end = match (self.has_fields, self.is_pretty()) { - (false, _) => "}", - (true, false) => " }", - (true, true) => "\n}", - }; - self.fmt.write_str(end) - }) + let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" }; + self.result.and_then(|_| write!(self.fmt, "{}}}", prefix)) } fn is_pretty(&self) -> bool { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index aa0d0a1539a..856e7569f1c 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -32,7 +32,7 @@ pub use self::num::radix; pub use self::num::Radix; pub use self::num::RadixFmt; -pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugMap}; +pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap}; mod num; mod float; @@ -644,7 +644,7 @@ impl<'a> Formatter<'a> { /// // prints "Foo { bar: 10, baz: "Hello World" }" /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", reason = "method was just created")] #[inline] pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> { builders::debug_struct_new(self, name) @@ -673,12 +673,42 @@ impl<'a> Formatter<'a> { /// // prints "Foo(10, "Hello World")" /// println!("{:?}", Foo(10, "Hello World".to_string())); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", reason = "method was just created")] #[inline] pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> { builders::debug_tuple_new(self, name) } + /// Creates a `DebugList` builder designed to assist with creation of + /// `fmt::Debug` implementations for list-like structures. + /// + /// # Examples + /// + /// ```rust + /// # #![feature(debug_builders, core)] + /// use std::fmt; + /// + /// struct Foo(Vec); + /// + /// impl fmt::Debug for Foo { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// let mut builder = fmt.debug_list(); + /// for i in &self.0 { + /// builder = builder.entry(i); + /// } + /// builder.finish() + /// } + /// } + /// + /// // prints "Foo { 10, 11 }" + /// println!("{:?}", Foo(vec![10, 11])); + /// ``` + #[unstable(feature = "debug_builders", reason = "method was just created")] + #[inline] + pub fn debug_list<'b>(&'b mut self) -> DebugList<'b, 'a> { + builders::debug_list_new(self) + } + /// Creates a `DebugSet` builder designed to assist with creation of /// `fmt::Debug` implementations for set-like structures. /// @@ -692,7 +722,7 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// let mut builder = fmt.debug_set("Foo"); + /// let mut builder = fmt.debug_set(); /// for i in &self.0 { /// builder = builder.entry(i); /// } @@ -703,10 +733,10 @@ impl<'a> Formatter<'a> { /// // prints "Foo { 10, 11 }" /// println!("{:?}", Foo(vec![10, 11])); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", reason = "method was just created")] #[inline] - pub fn debug_set<'b>(&'b mut self, name: &str) -> DebugSet<'b, 'a> { - builders::debug_set_new(self, name) + pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> { + builders::debug_set_new(self) } /// Creates a `DebugMap` builder designed to assist with creation of @@ -722,7 +752,7 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// let mut builder = fmt.debug_map("Foo"); + /// let mut builder = fmt.debug_map(); /// for &(ref key, ref value) in &self.0 { /// builder = builder.entry(key, value); /// } @@ -733,10 +763,10 @@ impl<'a> Formatter<'a> { /// // prints "Foo { "A": 10, "B": 11 }" /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])); /// ``` - #[unstable(feature = "core", reason = "method was just created")] + #[unstable(feature = "debug_builders", reason = "method was just created")] #[inline] - pub fn debug_map<'b>(&'b mut self, name: &str) -> DebugMap<'b, 'a> { - builders::debug_map_new(self, name) + pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> { + builders::debug_map_new(self) } } diff --git a/src/libcoretest/fmt/builders.rs b/src/libcoretest/fmt/builders.rs index b2fbc90be59..885ee3f9c3b 100644 --- a/src/libcoretest/fmt/builders.rs +++ b/src/libcoretest/fmt/builders.rs @@ -211,12 +211,12 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo").finish() + fmt.debug_map().finish() } } - assert_eq!("Foo {}", format!("{:?}", Foo)); - assert_eq!("Foo {}", format!("{:#?}", Foo)); + assert_eq!("{}", format!("{:?}", Foo)); + assert_eq!("{}", format!("{:#?}", Foo)); } #[test] @@ -225,15 +225,15 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo") + fmt.debug_map() .entry(&"bar", &true) .finish() } } - assert_eq!("Foo { \"bar\": true }", format!("{:?}", Foo)); + assert_eq!("{\"bar\": true}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ \"bar\": true }", format!("{:#?}", Foo)); @@ -245,16 +245,16 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo") + fmt.debug_map() .entry(&"bar", &true) .entry(&10i32, &format_args!("{}/{}", 10i32, 20i32)) .finish() } } - assert_eq!("Foo { \"bar\": true, 10: 10/20 }", format!("{:?}", Foo)); + assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ \"bar\": true, 10: 10/20 }", @@ -267,7 +267,7 @@ mod debug_map { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Foo") + fmt.debug_map() .entry(&"bar", &true) .entry(&10i32, &format_args!("{}/{}", 10i32, 20i32)) .finish() @@ -278,23 +278,23 @@ mod debug_map { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_map("Bar") + fmt.debug_map() .entry(&"foo", &Foo) .entry(&Foo, &"world") .finish() } } - assert_eq!("Bar { \"foo\": Foo { \"bar\": true, 10: 10/20 }, \ - Foo { \"bar\": true, 10: 10/20 }: \"world\" }", + assert_eq!("{\"foo\": {\"bar\": true, 10: 10/20}, \ + {\"bar\": true, 10: 10/20}: \"world\"}", format!("{:?}", Bar)); assert_eq!( -"Bar { - \"foo\": Foo { +"{ + \"foo\": { \"bar\": true, 10: 10/20 }, - Foo { + { \"bar\": true, 10: 10/20 }: \"world\" @@ -312,12 +312,12 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo").finish() + fmt.debug_set().finish() } } - assert_eq!("Foo {}", format!("{:?}", Foo)); - assert_eq!("Foo {}", format!("{:#?}", Foo)); + assert_eq!("{}", format!("{:?}", Foo)); + assert_eq!("{}", format!("{:#?}", Foo)); } #[test] @@ -326,15 +326,15 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo") + fmt.debug_set() .entry(&true) .finish() } } - assert_eq!("Foo { true }", format!("{:?}", Foo)); + assert_eq!("{true}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ true }", format!("{:#?}", Foo)); @@ -346,16 +346,16 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo") + fmt.debug_set() .entry(&true) .entry(&format_args!("{}/{}", 10i32, 20i32)) .finish() } } - assert_eq!("Foo { true, 10/20 }", format!("{:?}", Foo)); + assert_eq!("{true, 10/20}", format!("{:?}", Foo)); assert_eq!( -"Foo { +"{ true, 10/20 }", @@ -368,7 +368,7 @@ mod debug_set { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Foo") + fmt.debug_set() .entry(&true) .entry(&format_args!("{}/{}", 10i32, 20i32)) .finish() @@ -379,18 +379,18 @@ mod debug_set { impl fmt::Debug for Bar { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_set("Bar") + fmt.debug_set() .entry(&Foo) .entry(&"world") .finish() } } - assert_eq!("Bar { Foo { true, 10/20 }, \"world\" }", + assert_eq!("{{true, 10/20}, \"world\"}", format!("{:?}", Bar)); assert_eq!( -"Bar { - Foo { +"{ + { true, 10/20 }, @@ -399,3 +399,100 @@ mod debug_set { format!("{:#?}", Bar)); } } + +mod debug_list { + use std::fmt; + + #[test] + fn test_empty() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list().finish() + } + } + + assert_eq!("[]", format!("{:?}", Foo)); + assert_eq!("[]", format!("{:#?}", Foo)); + } + + #[test] + fn test_single() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&true) + .finish() + } + } + + assert_eq!("[true]", format!("{:?}", Foo)); + assert_eq!( +"[ + true +]", + format!("{:#?}", Foo)); + } + + #[test] + fn test_multiple() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&true) + .entry(&format_args!("{}/{}", 10i32, 20i32)) + .finish() + } + } + + assert_eq!("[true, 10/20]", format!("{:?}", Foo)); + assert_eq!( +"[ + true, + 10/20 +]", + format!("{:#?}", Foo)); + } + + #[test] + fn test_nested() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&true) + .entry(&format_args!("{}/{}", 10i32, 20i32)) + .finish() + } + } + + struct Bar; + + impl fmt::Debug for Bar { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_list() + .entry(&Foo) + .entry(&"world") + .finish() + } + } + + assert_eq!("[[true, 10/20], \"world\"]", + format!("{:?}", Bar)); + assert_eq!( +"[ + [ + true, + 10/20 + ], + \"world\" +]", + format!("{:#?}", Bar)); + } +} diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f9e1cb877b6..fd62729cd8f 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1226,14 +1226,11 @@ impl Debug for HashMap where K: Eq + Hash + Debug, V: Debug, S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, (k, v)) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}: {:?}", *k, *v)); + let mut builder = f.debug_map(); + for (k, v) in self.iter() { + builder = builder.entry(k, v); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 0933b4f662a..44c3d8262a7 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -614,14 +614,11 @@ impl fmt::Debug for HashSet S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "{{")); - - for (i, x) in self.iter().enumerate() { - if i != 0 { try!(write!(f, ", ")); } - try!(write!(f, "{:?}", *x)); + let mut builder = f.debug_set(); + for x in self { + builder = builder.entry(x); } - - write!(f, "}}") + builder.finish() } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 5f5f2fed567..b7cb8f9ed50 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -128,6 +128,7 @@ #![feature(into_cow)] #![feature(slice_patterns)] #![feature(std_misc)] +#![feature(debug_builders)] #![cfg_attr(test, feature(test, rustc_private, std_misc))] // Don't link to std. We are std. From b82bcec7ce67a60adcc054670487fe534195f6d6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 28 Mar 2015 11:24:26 -0700 Subject: [PATCH 2/4] Fold collections debug impls Also convert [T]'s Debug impl. The behavior of the alternate flag here's changing. --- src/libcollections/btree/map.rs | 6 +----- src/libcollections/btree/set.rs | 6 +----- src/libcollections/linked_list.rs | 6 +----- src/libcore/fmt/mod.rs | 17 +---------------- src/libstd/collections/hash/map.rs | 6 +----- src/libstd/collections/hash/set.rs | 6 +----- 6 files changed, 6 insertions(+), 41 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 93978e31de5..e1d007f0ac4 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -904,11 +904,7 @@ impl Ord for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut builder = f.debug_map(); - for (k, v) in self { - builder = builder.entry(k, v); - } - builder.finish() + self.iter().fold(f.debug_map(), |b, (k, v)| b.entry(k, v)).finish() } } diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index db0cdd30b1b..840110b5b27 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -628,11 +628,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeSet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut builder = f.debug_set(); - for x in self { - builder = builder.entry(x); - } - builder.finish() + self.iter().fold(f.debug_set(), |b, e| b.entry(e)).finish() } } diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 56c880ca6e2..581bab5759f 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -927,11 +927,7 @@ impl Clone for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut builder = f.debug_list(); - for e in self { - builder = builder.entry(e); - } - builder.finish() + self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish() } } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 856e7569f1c..29750a0a496 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1017,22 +1017,7 @@ impl<'a> Debug for &'a (any::Any+'a) { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for [T] { fn fmt(&self, f: &mut Formatter) -> Result { - if f.flags & (1 << (FlagV1::Alternate as u32)) == 0 { - try!(write!(f, "[")); - } - let mut is_first = true; - for x in self { - if is_first { - is_first = false; - } else { - try!(write!(f, ", ")); - } - try!(write!(f, "{:?}", *x)) - } - if f.flags & (1 << (FlagV1::Alternate as u32)) == 0 { - try!(write!(f, "]")); - } - Ok(()) + self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish() } } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index fd62729cd8f..50f405ea3b8 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1226,11 +1226,7 @@ impl Debug for HashMap where K: Eq + Hash + Debug, V: Debug, S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut builder = f.debug_map(); - for (k, v) in self.iter() { - builder = builder.entry(k, v); - } - builder.finish() + self.iter().fold(f.debug_map(), |b, (k, v)| b.entry(k, v)).finish() } } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 44c3d8262a7..d3dae88265a 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -614,11 +614,7 @@ impl fmt::Debug for HashSet S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut builder = f.debug_set(); - for x in self { - builder = builder.entry(x); - } - builder.finish() + self.iter().fold(f.debug_set(), |b, e| b.entry(e)).finish() } } From 842e6cf63e632473b335cffeeaeb305c45d546fa Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 28 Mar 2015 11:30:03 -0700 Subject: [PATCH 3/4] Fold in debug builder doc examples --- src/libcore/fmt/mod.rs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 29750a0a496..e2b12b1c20d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -692,11 +692,7 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// let mut builder = fmt.debug_list(); - /// for i in &self.0 { - /// builder = builder.entry(i); - /// } - /// builder.finish() + /// self.0.iter().fold(fmt.debug_list(), |b, e| b.entry(e)).finish() /// } /// } /// @@ -722,11 +718,7 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// let mut builder = fmt.debug_set(); - /// for i in &self.0 { - /// builder = builder.entry(i); - /// } - /// builder.finish() + /// self.0.iter().fold(fmt.debug_set(), |b, e| b.entry(e)).finish() /// } /// } /// @@ -752,11 +744,7 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// let mut builder = fmt.debug_map(); - /// for &(ref key, ref value) in &self.0 { - /// builder = builder.entry(key, value); - /// } - /// builder.finish() + /// self.0.iter().fold(fmt.debug_map(), |b, (k, v)| b.entry(k, v)).finish() /// } /// } /// From 3c0c8fc43a6dddda37c9e833279e0f8859a05f1c Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 28 Mar 2015 15:55:02 -0700 Subject: [PATCH 4/4] Oops fix output examples --- src/libcore/fmt/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index e2b12b1c20d..bd802cfb559 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -696,7 +696,7 @@ impl<'a> Formatter<'a> { /// } /// } /// - /// // prints "Foo { 10, 11 }" + /// // prints "[10, 11]" /// println!("{:?}", Foo(vec![10, 11])); /// ``` #[unstable(feature = "debug_builders", reason = "method was just created")] @@ -722,7 +722,7 @@ impl<'a> Formatter<'a> { /// } /// } /// - /// // prints "Foo { 10, 11 }" + /// // prints "{10, 11}" /// println!("{:?}", Foo(vec![10, 11])); /// ``` #[unstable(feature = "debug_builders", reason = "method was just created")] @@ -744,11 +744,11 @@ impl<'a> Formatter<'a> { /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - /// self.0.iter().fold(fmt.debug_map(), |b, (k, v)| b.entry(k, v)).finish() + /// self.0.iter().fold(fmt.debug_map(), |b, &(ref k, ref v)| b.entry(k, v)).finish() /// } /// } /// - /// // prints "Foo { "A": 10, "B": 11 }" + /// // prints "{"A": 10, "B": 11}" /// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])); /// ``` #[unstable(feature = "debug_builders", reason = "method was just created")]