Skip to content

Commit bf08789

Browse files
committed
Keep access to private Formatter fields in Formatter methods
1 parent e0e7ac3 commit bf08789

File tree

2 files changed

+49
-43
lines changed

2 files changed

+49
-43
lines changed

src/libcore/fmt/builders.rs

+28-43
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,29 @@
1010

1111
use fmt;
1212

13-
struct PadAdapter<'a, 'b: 'a> {
14-
fmt: &'a mut fmt::Formatter<'b>,
13+
struct PadAdapter<'a> {
14+
buf: &'a mut (fmt::Write + 'a),
1515
on_newline: bool,
1616
}
1717

18-
impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
19-
fn new(fmt: &'a mut fmt::Formatter<'b>) -> PadAdapter<'a, 'b> {
20-
PadAdapter {
21-
fmt,
22-
on_newline: false,
23-
}
24-
}
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-
}
18+
impl<'a> PadAdapter<'a> {
19+
fn wrap<'b, 'c: 'a+'b>(fmt: &'c mut fmt::Formatter, slot: &'b mut Option<Self>)
20+
-> fmt::Formatter<'b> {
21+
fmt.wrap_buf(move |buf| {
22+
*slot = Some(PadAdapter {
23+
buf,
24+
on_newline: false,
25+
});
26+
slot.as_mut().unwrap()
27+
})
4328
}
4429
}
4530

46-
impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
31+
impl<'a> fmt::Write for PadAdapter<'a> {
4732
fn write_str(&mut self, mut s: &str) -> fmt::Result {
4833
while !s.is_empty() {
4934
if self.on_newline {
50-
self.fmt.write_str(" ")?;
35+
self.buf.write_str(" ")?;
5136
}
5237

5338
let split = match s.find('\n') {
@@ -60,7 +45,7 @@ impl<'a, 'b: 'a> fmt::Write for PadAdapter<'a, 'b> {
6045
s.len()
6146
}
6247
};
63-
self.fmt.write_str(&s[..split])?;
48+
self.buf.write_str(&s[..split])?;
6449
s = &s[split..];
6550
}
6651

@@ -131,13 +116,13 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
131116
};
132117

133118
if self.is_pretty() {
134-
use fmt::Write;
135-
let mut writer = PadAdapter::new(self.fmt);
119+
let mut slot = None;
120+
let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
136121
writer.write_str(prefix)?;
137122
writer.write_str("\n")?;
138123
writer.write_str(name)?;
139124
writer.write_str(": ")?;
140-
value.fmt(&mut writer.as_formatter())
125+
value.fmt(&mut writer)
141126
} else {
142127
write!(self.fmt, "{} {}: ", prefix, name)?;
143128
value.fmt(self.fmt)
@@ -228,11 +213,11 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
228213
};
229214

230215
if self.is_pretty() {
231-
use fmt::Write;
232-
let mut writer = PadAdapter::new(self.fmt);
216+
let mut slot = None;
217+
let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
233218
writer.write_str(prefix)?;
234219
writer.write_str("\n")?;
235-
value.fmt(&mut writer.as_formatter())
220+
value.fmt(&mut writer)
236221
} else {
237222
self.fmt.write_str(prefix)?;
238223
self.fmt.write_str(space)?;
@@ -276,14 +261,14 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
276261
fn entry(&mut self, entry: &fmt::Debug) {
277262
self.result = self.result.and_then(|_| {
278263
if self.is_pretty() {
279-
use fmt::Write;
280-
let mut writer = PadAdapter::new(self.fmt);
264+
let mut slot = None;
265+
let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
281266
writer.write_str(if self.has_fields {
282267
",\n"
283268
} else {
284269
"\n"
285270
})?;
286-
entry.fmt(&mut writer.as_formatter())
271+
entry.fmt(&mut writer)
287272
} else {
288273
if self.has_fields {
289274
self.fmt.write_str(", ")?
@@ -500,16 +485,16 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
500485
pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
501486
self.result = self.result.and_then(|_| {
502487
if self.is_pretty() {
503-
use fmt::Write;
504-
let mut writer = PadAdapter::new(self.fmt);
488+
let mut slot = None;
489+
let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot);
505490
writer.write_str(if self.has_fields {
506491
",\n"
507492
} else {
508493
"\n"
509494
})?;
510-
key.fmt(&mut writer.as_formatter())?;
495+
key.fmt(&mut writer)?;
511496
writer.write_str(": ")?;
512-
value.fmt(&mut writer.as_formatter())
497+
value.fmt(&mut writer)
513498
} else {
514499
if self.has_fields {
515500
self.fmt.write_str(", ")?

src/libcore/fmt/mod.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,27 @@ pub fn write(output: &mut Write, args: Arguments) -> Result {
10141014
}
10151015

10161016
impl<'a> Formatter<'a> {
1017+
fn wrap_buf<'b, 'c, F>(&'b mut self, wrap: F) -> Formatter<'c>
1018+
where 'b: 'c, F: FnOnce(&'b mut (Write+'b)) -> &'c mut (Write+'c)
1019+
{
1020+
Formatter {
1021+
// We want to change this
1022+
buf: wrap(self.buf),
1023+
1024+
// And preserve these
1025+
flags: self.flags,
1026+
fill: self.fill,
1027+
align: self.align,
1028+
width: self.width,
1029+
precision: self.precision,
1030+
1031+
// These only exist in the struct for the `run` method,
1032+
// which won’t be used together with this method.
1033+
curarg: self.curarg.clone(),
1034+
args: self.args,
1035+
}
1036+
}
1037+
10171038
// First up is the collection of functions used to execute a format string
10181039
// at runtime. This consumes all of the compile-time statics generated by
10191040
// the format! syntax extension.

0 commit comments

Comments
 (0)