Skip to content

Commit e0e7ac3

Browse files
committed
Make fmt::DebugList and friends forward formatting parameters
For example, formatting slice of integers with `{:04?}` should zero-pad each integer.
1 parent b9b82fd commit e0e7ac3

File tree

2 files changed

+113
-28
lines changed

2 files changed

+113
-28
lines changed

src/libcore/fmt/builders.rs

+58-28
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
2222
on_newline: false,
2323
}
2424
}
25+
26+
fn as_formatter(&mut self) -> fmt::Formatter {
27+
fmt::Formatter {
28+
// These only exist in the struct for the `Formatter::run` method,
29+
// which won’t be used.
30+
curarg: self.fmt.curarg.clone(),
31+
args: self.fmt.args,
32+
33+
// We want to preserve these
34+
flags: self.fmt.flags,
35+
fill: self.fmt.fill,
36+
align: self.fmt.align,
37+
width: self.fmt.width,
38+
precision: self.fmt.precision,
39+
40+
// And change this
41+
buf: self,
42+
}
43+
}
2544
}
2645

2746
impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
@@ -112,11 +131,16 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
112131
};
113132

114133
if self.is_pretty() {
134+
use fmt::Write;
115135
let mut writer = PadAdapter::new(self.fmt);
116-
fmt::write(&mut writer,
117-
format_args!("{}\n{}: {:#?}", prefix, name, value))
136+
writer.write_str(prefix)?;
137+
writer.write_str("\n")?;
138+
writer.write_str(name)?;
139+
writer.write_str(": ")?;
140+
value.fmt(&mut writer.as_formatter())
118141
} else {
119-
write!(self.fmt, "{} {}: {:?}", prefix, name, value)
142+
write!(self.fmt, "{} {}: ", prefix, name)?;
143+
value.fmt(self.fmt)
120144
}
121145
});
122146

@@ -204,10 +228,15 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
204228
};
205229

206230
if self.is_pretty() {
231+
use fmt::Write;
207232
let mut writer = PadAdapter::new(self.fmt);
208-
fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, value))
233+
writer.write_str(prefix)?;
234+
writer.write_str("\n")?;
235+
value.fmt(&mut writer.as_formatter())
209236
} else {
210-
write!(self.fmt, "{}{}{:?}", prefix, space, value)
237+
self.fmt.write_str(prefix)?;
238+
self.fmt.write_str(space)?;
239+
value.fmt(self.fmt)
211240
}
212241
});
213242

@@ -247,20 +276,19 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
247276
fn entry(&mut self, entry: &fmt::Debug) {
248277
self.result = self.result.and_then(|_| {
249278
if self.is_pretty() {
279+
use fmt::Write;
250280
let mut writer = PadAdapter::new(self.fmt);
251-
let prefix = if self.has_fields {
252-
","
281+
writer.write_str(if self.has_fields {
282+
",\n"
253283
} else {
254-
""
255-
};
256-
fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
284+
"\n"
285+
})?;
286+
entry.fmt(&mut writer.as_formatter())
257287
} else {
258-
let prefix = if self.has_fields {
259-
", "
260-
} else {
261-
""
262-
};
263-
write!(self.fmt, "{}{:?}", prefix, entry)
288+
if self.has_fields {
289+
self.fmt.write_str(", ")?
290+
}
291+
entry.fmt(self.fmt)
264292
}
265293
});
266294

@@ -472,21 +500,23 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
472500
pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
473501
self.result = self.result.and_then(|_| {
474502
if self.is_pretty() {
503+
use fmt::Write;
475504
let mut writer = PadAdapter::new(self.fmt);
476-
let prefix = if self.has_fields {
477-
","
505+
writer.write_str(if self.has_fields {
506+
",\n"
478507
} else {
479-
""
480-
};
481-
fmt::write(&mut writer,
482-
format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
508+
"\n"
509+
})?;
510+
key.fmt(&mut writer.as_formatter())?;
511+
writer.write_str(": ")?;
512+
value.fmt(&mut writer.as_formatter())
483513
} else {
484-
let prefix = if self.has_fields {
485-
", "
486-
} else {
487-
""
488-
};
489-
write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
514+
if self.has_fields {
515+
self.fmt.write_str(", ")?
516+
}
517+
key.fmt(self.fmt)?;
518+
self.fmt.write_str(": ")?;
519+
value.fmt(self.fmt)
490520
}
491521
});
492522

src/libcore/tests/fmt/builders.rs

+55
Original file line numberDiff line numberDiff line change
@@ -496,3 +496,58 @@ mod debug_list {
496496
format!("{:#?}", Bar));
497497
}
498498
}
499+
500+
#[test]
501+
fn test_formatting_parameters_are_forwarded() {
502+
use std::collections::{BTreeMap, BTreeSet};
503+
#[derive(Debug)]
504+
struct Foo {
505+
bar: u32,
506+
baz: u32,
507+
}
508+
let struct_ = Foo { bar: 1024, baz: 7 };
509+
let tuple = (1024, 7);
510+
let list = [1024, 7];
511+
let mut map = BTreeMap::new();
512+
map.insert("bar", 1024);
513+
map.insert("baz", 7);
514+
let mut set = BTreeSet::new();
515+
set.insert(1024);
516+
set.insert(7);
517+
518+
assert_eq!(format!("{:03?}", struct_), "Foo { bar: 1024, baz: 007 }");
519+
assert_eq!(format!("{:03?}", tuple), "(1024, 007)");
520+
assert_eq!(format!("{:03?}", list), "[1024, 007]");
521+
assert_eq!(format!("{:03?}", map), r#"{"bar": 1024, "baz": 007}"#);
522+
assert_eq!(format!("{:03?}", set), "{007, 1024}");
523+
assert_eq!(format!("{:#03?}", struct_), "
524+
Foo {
525+
bar: 1024,
526+
baz: 007
527+
}
528+
".trim());
529+
assert_eq!(format!("{:#03?}", tuple), "
530+
(
531+
1024,
532+
007
533+
)
534+
".trim());
535+
assert_eq!(format!("{:#03?}", list), "
536+
[
537+
1024,
538+
007
539+
]
540+
".trim());
541+
assert_eq!(format!("{:#03?}", map), r#"
542+
{
543+
"bar": 1024,
544+
"baz": 007
545+
}
546+
"#.trim());
547+
assert_eq!(format!("{:#03?}", set), "
548+
{
549+
007,
550+
1024
551+
}
552+
".trim());
553+
}

0 commit comments

Comments
 (0)