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 | 138 +++++++++++++++---------- 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, 275 insertions(+), 129 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index d2b45f4b0492b..93978e31de57d 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 08ee5801482fd..db0cdd30b1b1f 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 f774c1505b82b..c769b3df37f62 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 908c78a17f4f9..56c880ca6e265 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 07f029cc15e2f..f61a7f2d30c62 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -177,22 +177,54 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> { } } +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: &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> { - fmt: &'a mut fmt::Formatter<'b>, - result: fmt::Result, - has_fields: bool, + inner: DebugInner<'a, 'b>, } -pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugSet<'a, 'b> { - let result = write!(fmt, "{} {{", name); +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("}")) } +} - 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_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 + } + + /// 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 aa0d0a1539a30..856e7569f1c27 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 b2fbc90be5914..885ee3f9c3be2 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 f9e1cb877b60b..fd62729cd8f2b 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 0933b4f662a9d..44c3d8262a7b1 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 5f5f2fed56732..b7cb8f9ed50fd 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 93978e31de57d..e1d007f0ac497 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 db0cdd30b1b1f..840110b5b276f 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 56c880ca6e265..581bab5759fd7 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 856e7569f1c27..29750a0a4962a 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 fd62729cd8f2b..50f405ea3b8e9 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 44c3d8262a7b1..d3dae88265a78 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 29750a0a4962a..e2b12b1c20d1e 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 e2b12b1c20d1e..bd802cfb55948 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")]