Restructure debug builders to minimize codegen

Switching from generic bounds to trait objects and having un-inlined
inner methods should cut down on the size of Debug impls, since we care
about the speed of a Debug implementation way less than binary bloat.
This commit is contained in:
Steven Fackler 2015-03-06 21:46:30 -08:00
parent e3656bd81b
commit 8121cf077c

View File

@ -63,8 +63,13 @@ pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str)
impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
/// Adds a new field to the generated struct output.
#[unstable(feature = "core", reason = "method was just created")]
pub fn field<S>(mut self, name: &str, value: &S) -> DebugStruct<'a, 'b>
where S: fmt::Debug {
#[inline]
pub fn field(mut self, name: &str, value: &fmt::Debug) -> DebugStruct<'a, 'b> {
self.field_inner(name, value);
self
}
fn field_inner(&mut self, name: &str, value: &fmt::Debug) {
self.result = self.result.and_then(|_| {
let prefix = if self.has_fields {
","
@ -81,13 +86,18 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
});
self.has_fields = true;
self
}
/// Consumes the `DebugStruct`, finishing output and returning any error
/// encountered.
#[unstable(feature = "core", reason = "method was just created")]
#[inline]
pub fn finish(mut self) -> fmt::Result {
self.finish_inner();
self.result
}
fn finish_inner(&mut self) {
if self.has_fields {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
@ -97,7 +107,6 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
}
});
}
self.result
}
fn is_pretty(&self) -> bool {
@ -127,7 +136,13 @@ pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> D
impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
/// Adds a new field to the generated tuple struct output.
#[unstable(feature = "core", reason = "method was just created")]
pub fn field<S>(mut self, value: &S) -> DebugTuple<'a, 'b> where S: fmt::Debug {
#[inline]
pub fn field(mut self, value: &fmt::Debug) -> DebugTuple<'a, 'b> {
self.field_inner(value);
self
}
fn field_inner(&mut self, value: &fmt::Debug) {
self.result = self.result.and_then(|_| {
let (prefix, space) = if self.has_fields {
(",", " ")
@ -144,13 +159,18 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
});
self.has_fields = true;
self
}
/// Consumes the `DebugTuple`, finishing output and returning any error
/// encountered.
#[unstable(feature = "core", reason = "method was just created")]
#[inline]
pub fn finish(mut self) -> fmt::Result {
self.finish_inner();
self.result
}
fn finish_inner(&mut self) {
if self.has_fields {
self.result = self.result.and_then(|_| {
if self.is_pretty() {
@ -160,7 +180,6 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
}
});
}
self.result
}
fn is_pretty(&self) -> bool {
@ -190,7 +209,13 @@ pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> Deb
impl<'a, 'b: 'a> DebugSet<'a, 'b> {
/// Adds a new entry to the set output.
#[unstable(feature = "core", reason = "method was just created")]
pub fn entry<S>(mut self, entry: &S) -> DebugSet<'a, 'b> where S: fmt::Debug {
#[inline]
pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> {
self.entry_inner(entry);
self
}
fn entry_inner(&mut self, entry: &fmt::Debug) {
self.result = self.result.and_then(|_| {
let prefix = if self.has_fields {
","
@ -207,21 +232,26 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
});
self.has_fields = true;
self
}
/// Consumes the `DebugSet`, finishing output and returning any error
/// encountered.
#[unstable(feature = "core", reason = "method was just created")]
pub fn finish(self) -> fmt::Result {
self.result.and_then(|_| {
#[inline]
pub fn finish(mut self) -> fmt::Result {
self.finish_inner();
self.result
}
fn finish_inner(&mut self) {
self.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)
})
});
}
fn is_pretty(&self) -> bool {
@ -251,8 +281,13 @@ pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> Deb
impl<'a, 'b: 'a> DebugMap<'a, 'b> {
/// Adds a new entry to the map output.
#[unstable(feature = "core", reason = "method was just created")]
pub fn entry<K, V>(mut self, key: &K, value: &V) -> DebugMap<'a, 'b>
where K: fmt::Debug, V: fmt::Debug {
#[inline]
pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> {
self.entry_inner(key, value);
self
}
fn entry_inner(&mut self, key: &fmt::Debug, value: &fmt::Debug) {
self.result = self.result.and_then(|_| {
let prefix = if self.has_fields {
","
@ -269,21 +304,26 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
});
self.has_fields = true;
self
}
/// Consumes the `DebugMap`, finishing output and returning any error
/// encountered.
#[unstable(feature = "core", reason = "method was just created")]
pub fn finish(self) -> fmt::Result {
self.result.and_then(|_| {
#[inline]
pub fn finish(mut self) -> fmt::Result {
self.finish_inner();
self.result
}
fn finish_inner(&mut self) {
self.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)
})
});
}
fn is_pretty(&self) -> bool {