Include trailing comma in multiline Debug representation

This commit changes the behavior of Formatter::debug_struct,
debug_tuple, debug_list, debug_set, and debug_map to render trailing
commas in {:#?} mode, which is the dominant style in modern Rust code.

Before:

    Language {
        name: "Rust",
        trailing_commas: false
    }

After:

    Language {
        name: "Rust",
        trailing_commas: true,
    }
This commit is contained in:
David Tolnay 2019-04-03 07:30:08 -07:00
parent a781c47243
commit cfd31fb4df
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82
28 changed files with 226 additions and 252 deletions

View file

@ -11,7 +11,7 @@ impl<'a> PadAdapter<'a> {
fmt.wrap_buf(move |buf| {
*slot = Some(PadAdapter {
buf,
on_newline: false,
on_newline: true,
});
slot.as_mut().unwrap()
})
@ -128,22 +128,21 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
#[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(|_| {
let prefix = if self.has_fields {
","
} else {
" {"
};
if self.is_pretty() {
if !self.has_fields {
self.fmt.write_str(" {\n")?;
}
let mut slot = None;
let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
writer.write_str(prefix)?;
writer.write_str("\n")?;
writer.write_str(name)?;
writer.write_str(": ")?;
value.fmt(&mut writer)
value.fmt(&mut writer)?;
writer.write_str(",\n")
} else {
write!(self.fmt, "{} {}: ", prefix, name)?;
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)
}
});
@ -184,7 +183,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
if self.has_fields {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
self.fmt.write_str("\n}")
self.fmt.write_str("}")
} else {
self.fmt.write_str(" }")
}
@ -275,21 +274,17 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
#[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(|_| {
let (prefix, space) = if self.fields > 0 {
(",", " ")
} else {
("(", "")
};
if self.is_pretty() {
if self.fields == 0 {
self.fmt.write_str("(\n")?;
}
let mut slot = None;
let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
writer.write_str(prefix)?;
writer.write_str("\n")?;
value.fmt(&mut writer)
value.fmt(&mut writer)?;
writer.write_str(",\n")
} else {
let prefix = if self.fields == 0 { "(" } else { ", " };
self.fmt.write_str(prefix)?;
self.fmt.write_str(space)?;
value.fmt(self.fmt)
}
});
@ -326,10 +321,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
pub fn finish(&mut self) -> fmt::Result {
if self.fields > 0 {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
self.fmt.write_str("\n")?;
}
if self.fields == 1 && self.empty_name {
if self.fields == 1 && self.empty_name && !self.is_pretty() {
self.fmt.write_str(",")?;
}
self.fmt.write_str(")")
@ -353,14 +345,13 @@ 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 writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
writer.write_str(if self.has_fields {
",\n"
} else {
"\n"
})?;
entry.fmt(&mut writer)
entry.fmt(&mut writer)?;
writer.write_str(",\n")
} else {
if self.has_fields {
self.fmt.write_str(", ")?
@ -372,15 +363,6 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
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.alternate()
}
@ -421,7 +403,7 @@ pub struct DebugSet<'a, 'b: 'a> {
}
pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
let result = write!(fmt, "{{");
let result = fmt.write_str("{");
DebugSet {
inner: DebugInner {
fmt,
@ -519,7 +501,6 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
self.inner.finish();
self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
}
}
@ -559,7 +540,7 @@ pub struct DebugList<'a, 'b: 'a> {
}
pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
let result = write!(fmt, "[");
let result = fmt.write_str("[");
DebugList {
inner: DebugInner {
fmt,
@ -657,7 +638,6 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
self.inner.finish();
self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
}
}
@ -699,7 +679,7 @@ pub struct DebugMap<'a, 'b: 'a> {
}
pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
let result = write!(fmt, "{{");
let result = fmt.write_str("{");
DebugMap {
fmt,
result,
@ -734,16 +714,15 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'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 writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
writer.write_str(if self.has_fields {
",\n"
} else {
"\n"
})?;
key.fmt(&mut writer)?;
writer.write_str(": ")?;
value.fmt(&mut writer)
value.fmt(&mut writer)?;
writer.write_str(",\n")
} else {
if self.has_fields {
self.fmt.write_str(", ")?
@ -818,12 +797,7 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
/// ```
#[stable(feature = "debug_builders", since = "1.2.0")]
pub fn finish(&mut self) -> fmt::Result {
let prefix = if self.is_pretty() && self.has_fields {
"\n"
} else {
""
};
self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
self.result.and_then(|_| self.fmt.write_str("}"))
}
fn is_pretty(&self) -> bool {

View file

@ -30,7 +30,7 @@ mod debug_struct {
assert_eq!("Foo { bar: true }", format!("{:?}", Foo));
assert_eq!(
"Foo {
bar: true
bar: true,
}",
format!("{:#?}", Foo));
}
@ -52,7 +52,7 @@ mod debug_struct {
assert_eq!(
"Foo {
bar: true,
baz: 10/20
baz: 10/20,
}",
format!("{:#?}", Foo));
}
@ -87,9 +87,9 @@ mod debug_struct {
"Bar {
foo: Foo {
bar: true,
baz: 10/20
baz: 10/20,
},
hello: \"world\"
hello: \"world\",
}",
format!("{:#?}", Bar));
}
@ -127,7 +127,7 @@ mod debug_tuple {
assert_eq!("Foo(true)", format!("{:?}", Foo));
assert_eq!(
"Foo(
true
true,
)",
format!("{:#?}", Foo));
}
@ -149,7 +149,7 @@ mod debug_tuple {
assert_eq!(
"Foo(
true,
10/20
10/20,
)",
format!("{:#?}", Foo));
}
@ -184,9 +184,9 @@ mod debug_tuple {
"Bar(
Foo(
true,
10/20
10/20,
),
\"world\"
\"world\",
)",
format!("{:#?}", Bar));
}
@ -224,7 +224,7 @@ mod debug_map {
assert_eq!("{\"bar\": true}", format!("{:?}", Foo));
assert_eq!(
"{
\"bar\": true
\"bar\": true,
}",
format!("{:#?}", Foo));
}
@ -246,7 +246,7 @@ mod debug_map {
assert_eq!(
"{
\"bar\": true,
10: 10/20
10: 10/20,
}",
format!("{:#?}", Foo));
}
@ -282,12 +282,12 @@ mod debug_map {
"{
\"foo\": {
\"bar\": true,
10: 10/20
10: 10/20,
},
{
\"bar\": true,
10: 10/20
}: \"world\"
10: 10/20,
}: \"world\",
}",
format!("{:#?}", Bar));
}
@ -325,7 +325,7 @@ mod debug_set {
assert_eq!("{true}", format!("{:?}", Foo));
assert_eq!(
"{
true
true,
}",
format!("{:#?}", Foo));
}
@ -347,7 +347,7 @@ mod debug_set {
assert_eq!(
"{
true,
10/20
10/20,
}",
format!("{:#?}", Foo));
}
@ -382,9 +382,9 @@ mod debug_set {
"{
{
true,
10/20
10/20,
},
\"world\"
\"world\",
}",
format!("{:#?}", Bar));
}
@ -422,7 +422,7 @@ mod debug_list {
assert_eq!("[true]", format!("{:?}", Foo));
assert_eq!(
"[
true
true,
]",
format!("{:#?}", Foo));
}
@ -444,7 +444,7 @@ mod debug_list {
assert_eq!(
"[
true,
10/20
10/20,
]",
format!("{:#?}", Foo));
}
@ -479,9 +479,9 @@ mod debug_list {
"[
[
true,
10/20
10/20,
],
\"world\"
\"world\",
]",
format!("{:#?}", Bar));
}
@ -513,31 +513,31 @@ fn test_formatting_parameters_are_forwarded() {
assert_eq!(format!("{:#03?}", struct_), "
Foo {
bar: 1024,
baz: 007
baz: 007,
}
".trim());
assert_eq!(format!("{:#03?}", tuple), "
(
1024,
007
007,
)
".trim());
assert_eq!(format!("{:#03?}", list), "
[
1024,
007
007,
]
".trim());
assert_eq!(format!("{:#03?}", map), r#"
{
"bar": 1024,
"baz": 007
"baz": 007,
}
"#.trim());
assert_eq!(format!("{:#03?}", set), "
{
007,
1024
1024,
}
".trim());
}