Skip to content

Commit 227b46b

Browse files
committed
Auto merge of rust-lang#23810 - sfackler:debug-collections, r=alexcrichton
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]
2 parents 27af78c + 3c0c8fc commit 227b46b

File tree

10 files changed

+259
-160
lines changed

10 files changed

+259
-160
lines changed

src/libcollections/btree/map.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -904,14 +904,7 @@ impl<K: Ord, V: Ord> Ord for BTreeMap<K, V> {
904904
#[stable(feature = "rust1", since = "1.0.0")]
905905
impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
906906
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
907-
try!(write!(f, "{{"));
908-
909-
for (i, (k, v)) in self.iter().enumerate() {
910-
if i != 0 { try!(write!(f, ", ")); }
911-
try!(write!(f, "{:?}: {:?}", *k, *v));
912-
}
913-
914-
write!(f, "}}")
907+
self.iter().fold(f.debug_map(), |b, (k, v)| b.entry(k, v)).finish()
915908
}
916909
}
917910

src/libcollections/btree/set.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -628,14 +628,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>> for &'a BTreeSet<T> {
628628
#[stable(feature = "rust1", since = "1.0.0")]
629629
impl<T: Debug> Debug for BTreeSet<T> {
630630
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
631-
try!(write!(f, "{{"));
632-
633-
for (i, x) in self.iter().enumerate() {
634-
if i != 0 { try!(write!(f, ", ")); }
635-
try!(write!(f, "{:?}", *x));
636-
}
637-
638-
write!(f, "}}")
631+
self.iter().fold(f.debug_set(), |b, e| b.entry(e)).finish()
639632
}
640633
}
641634

src/libcollections/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#![feature(str_char)]
4141
#![feature(convert)]
4242
#![feature(slice_patterns)]
43+
#![feature(debug_builders)]
4344
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
4445
#![cfg_attr(test, allow(deprecated))] // rand
4546

src/libcollections/linked_list.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -927,14 +927,7 @@ impl<A: Clone> Clone for LinkedList<A> {
927927
#[stable(feature = "rust1", since = "1.0.0")]
928928
impl<A: fmt::Debug> fmt::Debug for LinkedList<A> {
929929
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
930-
try!(write!(f, "["));
931-
932-
for (i, e) in self.iter().enumerate() {
933-
if i != 0 { try!(write!(f, ", ")); }
934-
try!(write!(f, "{:?}", *e));
935-
}
936-
937-
write!(f, "]")
930+
self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish()
938931
}
939932
}
940933

src/libcore/fmt/builders.rs

+85-53
Original file line numberDiff line numberDiff line change
@@ -177,64 +177,107 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
177177
}
178178
}
179179

180+
struct DebugInner<'a, 'b: 'a> {
181+
fmt: &'a mut fmt::Formatter<'b>,
182+
result: fmt::Result,
183+
has_fields: bool,
184+
}
185+
186+
impl<'a, 'b: 'a> DebugInner<'a, 'b> {
187+
fn entry(&mut self, entry: &fmt::Debug) {
188+
self.result = self.result.and_then(|_| {
189+
if self.is_pretty() {
190+
let mut writer = PadAdapter::new(self.fmt);
191+
let prefix = if self.has_fields { "," } else { "" };
192+
fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
193+
} else {
194+
let prefix = if self.has_fields { ", " } else { "" };
195+
write!(self.fmt, "{}{:?}", prefix, entry)
196+
}
197+
});
198+
199+
self.has_fields = true;
200+
}
201+
202+
pub fn finish(&mut self) {
203+
let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
204+
self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
205+
}
206+
207+
fn is_pretty(&self) -> bool {
208+
self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
209+
}
210+
}
211+
180212
/// A struct to help with `fmt::Debug` implementations.
181213
///
182214
/// Constructed by the `Formatter::debug_set` method.
183215
#[must_use]
184216
pub struct DebugSet<'a, 'b: 'a> {
185-
fmt: &'a mut fmt::Formatter<'b>,
186-
result: fmt::Result,
187-
has_fields: bool,
217+
inner: DebugInner<'a, 'b>,
188218
}
189219

190-
pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugSet<'a, 'b> {
191-
let result = write!(fmt, "{} {{", name);
220+
pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
221+
let result = write!(fmt, "{{");
192222
DebugSet {
193-
fmt: fmt,
194-
result: result,
195-
has_fields: false,
223+
inner: DebugInner {
224+
fmt: fmt,
225+
result: result,
226+
has_fields: false,
227+
}
196228
}
197229
}
198230

199231
impl<'a, 'b: 'a> DebugSet<'a, 'b> {
200232
/// Adds a new entry to the set output.
201233
#[unstable(feature = "debug_builders", reason = "method was just created")]
202234
pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> {
203-
self.result = self.result.and_then(|_| {
204-
let prefix = if self.has_fields {
205-
","
206-
} else {
207-
""
208-
};
209-
210-
if self.is_pretty() {
211-
let mut writer = PadAdapter::new(self.fmt);
212-
fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
213-
} else {
214-
write!(self.fmt, "{} {:?}", prefix, entry)
215-
}
216-
});
217-
218-
self.has_fields = true;
235+
self.inner.entry(entry);
219236
self
220237
}
221238

222239
/// Consumes the `DebugSet`, finishing output and returning any error
223240
/// encountered.
224241
#[unstable(feature = "debug_builders", reason = "method was just created")]
225-
pub fn finish(self) -> fmt::Result {
226-
self.result.and_then(|_| {
227-
let end = match (self.has_fields, self.is_pretty()) {
228-
(false, _) => "}",
229-
(true, false) => " }",
230-
(true, true) => "\n}",
231-
};
232-
self.fmt.write_str(end)
233-
})
242+
pub fn finish(mut self) -> fmt::Result {
243+
self.inner.finish();
244+
self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
234245
}
246+
}
235247

236-
fn is_pretty(&self) -> bool {
237-
self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
248+
/// A struct to help with `fmt::Debug` implementations.
249+
///
250+
/// Constructed by the `Formatter::debug_list` method.
251+
#[must_use]
252+
pub struct DebugList<'a, 'b: 'a> {
253+
inner: DebugInner<'a, 'b>,
254+
}
255+
256+
pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
257+
let result = write!(fmt, "[");
258+
DebugList {
259+
inner: DebugInner {
260+
fmt: fmt,
261+
result: result,
262+
has_fields: false,
263+
}
264+
}
265+
}
266+
267+
impl<'a, 'b: 'a> DebugList<'a, 'b> {
268+
/// Adds a new entry to the set output.
269+
#[unstable(feature = "debug_builders", reason = "method was just created")]
270+
pub fn entry(mut self, entry: &fmt::Debug) -> DebugList<'a, 'b> {
271+
self.inner.entry(entry);
272+
self
273+
}
274+
275+
/// Consumes the `DebugSet`, finishing output and returning any error
276+
/// encountered.
277+
#[unstable(feature = "debug_builders", reason = "method was just created")]
278+
pub fn finish(mut self) -> fmt::Result {
279+
self.inner.finish();
280+
self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
238281
}
239282
}
240283

@@ -248,8 +291,8 @@ pub struct DebugMap<'a, 'b: 'a> {
248291
has_fields: bool,
249292
}
250293

251-
pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugMap<'a, 'b> {
252-
let result = write!(fmt, "{} {{", name);
294+
pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
295+
let result = write!(fmt, "{{");
253296
DebugMap {
254297
fmt: fmt,
255298
result: result,
@@ -262,37 +305,26 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
262305
#[unstable(feature = "debug_builders", reason = "method was just created")]
263306
pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> {
264307
self.result = self.result.and_then(|_| {
265-
let prefix = if self.has_fields {
266-
","
267-
} else {
268-
""
269-
};
270-
271308
if self.is_pretty() {
272309
let mut writer = PadAdapter::new(self.fmt);
310+
let prefix = if self.has_fields { "," } else { "" };
273311
fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
274312
} else {
275-
write!(self.fmt, "{} {:?}: {:?}", prefix, key, value)
313+
let prefix = if self.has_fields { ", " } else { "" };
314+
write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
276315
}
277316
});
278317

279318
self.has_fields = true;
280-
281319
self
282320
}
283321

284322
/// Consumes the `DebugMap`, finishing output and returning any error
285323
/// encountered.
286324
#[unstable(feature = "debug_builders", reason = "method was just created")]
287325
pub fn finish(self) -> fmt::Result {
288-
self.result.and_then(|_| {
289-
let end = match (self.has_fields, self.is_pretty()) {
290-
(false, _) => "}",
291-
(true, false) => " }",
292-
(true, true) => "\n}",
293-
};
294-
self.fmt.write_str(end)
295-
})
326+
let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
327+
self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
296328
}
297329

298330
fn is_pretty(&self) -> bool {

src/libcore/fmt/mod.rs

+40-37
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub use self::num::radix;
3232
pub use self::num::Radix;
3333
pub use self::num::RadixFmt;
3434

35-
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugMap};
35+
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};
3636

3737
mod num;
3838
mod float;
@@ -644,7 +644,7 @@ impl<'a> Formatter<'a> {
644644
/// // prints "Foo { bar: 10, baz: "Hello World" }"
645645
/// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() });
646646
/// ```
647-
#[unstable(feature = "core", reason = "method was just created")]
647+
#[unstable(feature = "debug_builders", reason = "method was just created")]
648648
#[inline]
649649
pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> {
650650
builders::debug_struct_new(self, name)
@@ -673,12 +673,38 @@ impl<'a> Formatter<'a> {
673673
/// // prints "Foo(10, "Hello World")"
674674
/// println!("{:?}", Foo(10, "Hello World".to_string()));
675675
/// ```
676-
#[unstable(feature = "core", reason = "method was just created")]
676+
#[unstable(feature = "debug_builders", reason = "method was just created")]
677677
#[inline]
678678
pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> {
679679
builders::debug_tuple_new(self, name)
680680
}
681681

682+
/// Creates a `DebugList` builder designed to assist with creation of
683+
/// `fmt::Debug` implementations for list-like structures.
684+
///
685+
/// # Examples
686+
///
687+
/// ```rust
688+
/// # #![feature(debug_builders, core)]
689+
/// use std::fmt;
690+
///
691+
/// struct Foo(Vec<i32>);
692+
///
693+
/// impl fmt::Debug for Foo {
694+
/// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
695+
/// self.0.iter().fold(fmt.debug_list(), |b, e| b.entry(e)).finish()
696+
/// }
697+
/// }
698+
///
699+
/// // prints "[10, 11]"
700+
/// println!("{:?}", Foo(vec![10, 11]));
701+
/// ```
702+
#[unstable(feature = "debug_builders", reason = "method was just created")]
703+
#[inline]
704+
pub fn debug_list<'b>(&'b mut self) -> DebugList<'b, 'a> {
705+
builders::debug_list_new(self)
706+
}
707+
682708
/// Creates a `DebugSet` builder designed to assist with creation of
683709
/// `fmt::Debug` implementations for set-like structures.
684710
///
@@ -692,21 +718,17 @@ impl<'a> Formatter<'a> {
692718
///
693719
/// impl fmt::Debug for Foo {
694720
/// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
695-
/// let mut builder = fmt.debug_set("Foo");
696-
/// for i in &self.0 {
697-
/// builder = builder.entry(i);
698-
/// }
699-
/// builder.finish()
721+
/// self.0.iter().fold(fmt.debug_set(), |b, e| b.entry(e)).finish()
700722
/// }
701723
/// }
702724
///
703-
/// // prints "Foo { 10, 11 }"
725+
/// // prints "{10, 11}"
704726
/// println!("{:?}", Foo(vec![10, 11]));
705727
/// ```
706-
#[unstable(feature = "core", reason = "method was just created")]
728+
#[unstable(feature = "debug_builders", reason = "method was just created")]
707729
#[inline]
708-
pub fn debug_set<'b>(&'b mut self, name: &str) -> DebugSet<'b, 'a> {
709-
builders::debug_set_new(self, name)
730+
pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> {
731+
builders::debug_set_new(self)
710732
}
711733

712734
/// Creates a `DebugMap` builder designed to assist with creation of
@@ -722,21 +744,17 @@ impl<'a> Formatter<'a> {
722744
///
723745
/// impl fmt::Debug for Foo {
724746
/// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
725-
/// let mut builder = fmt.debug_map("Foo");
726-
/// for &(ref key, ref value) in &self.0 {
727-
/// builder = builder.entry(key, value);
728-
/// }
729-
/// builder.finish()
747+
/// self.0.iter().fold(fmt.debug_map(), |b, &(ref k, ref v)| b.entry(k, v)).finish()
730748
/// }
731749
/// }
732750
///
733-
/// // prints "Foo { "A": 10, "B": 11 }"
751+
/// // prints "{"A": 10, "B": 11}"
734752
/// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)]));
735753
/// ```
736-
#[unstable(feature = "core", reason = "method was just created")]
754+
#[unstable(feature = "debug_builders", reason = "method was just created")]
737755
#[inline]
738-
pub fn debug_map<'b>(&'b mut self, name: &str) -> DebugMap<'b, 'a> {
739-
builders::debug_map_new(self, name)
756+
pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> {
757+
builders::debug_map_new(self)
740758
}
741759
}
742760

@@ -987,22 +1005,7 @@ impl<'a> Debug for &'a (any::Any+'a) {
9871005
#[stable(feature = "rust1", since = "1.0.0")]
9881006
impl<T: Debug> Debug for [T] {
9891007
fn fmt(&self, f: &mut Formatter) -> Result {
990-
if f.flags & (1 << (FlagV1::Alternate as u32)) == 0 {
991-
try!(write!(f, "["));
992-
}
993-
let mut is_first = true;
994-
for x in self {
995-
if is_first {
996-
is_first = false;
997-
} else {
998-
try!(write!(f, ", "));
999-
}
1000-
try!(write!(f, "{:?}", *x))
1001-
}
1002-
if f.flags & (1 << (FlagV1::Alternate as u32)) == 0 {
1003-
try!(write!(f, "]"));
1004-
}
1005-
Ok(())
1008+
self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish()
10061009
}
10071010
}
10081011

0 commit comments

Comments
 (0)