Avoid doing double the work when measuring.
This commit is contained in:
parent
e0eaecfdf7
commit
d8660bb01f
@ -331,13 +331,11 @@ impl CDecl {
|
||||
Layout::Vertical => write_vertical(out, config, args),
|
||||
Layout::Horizontal => write_horizontal(out, config, args),
|
||||
Layout::Auto => {
|
||||
if out.line_length_for_align()
|
||||
+ out.measure(|out| write_horizontal(out, config, args))
|
||||
> config.line_length
|
||||
{
|
||||
if !out.try_write(
|
||||
|out| write_horizontal(out, config, args),
|
||||
config.line_length,
|
||||
) {
|
||||
write_vertical(out, config, args)
|
||||
} else {
|
||||
write_horizontal(out, config, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -304,14 +304,14 @@ impl Source for Function {
|
||||
condition.write_after(config, out);
|
||||
}
|
||||
|
||||
let option_1 = out.measure(|out| write_1(self, config, out));
|
||||
|
||||
if (config.function.args == Layout::Auto && option_1 <= config.line_length)
|
||||
|| config.function.args == Layout::Horizontal
|
||||
{
|
||||
write_1(self, config, out);
|
||||
} else {
|
||||
write_2(self, config, out);
|
||||
match config.function.args {
|
||||
Layout::Horizontal => write_1(self, config, out),
|
||||
Layout::Vertical => write_2(self, config, out),
|
||||
Layout::Auto => {
|
||||
if !out.try_write(|out| write_1(self, config, out), config.line_length) {
|
||||
write_2(self, config, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,18 +17,6 @@ pub enum ListType<'a> {
|
||||
Cap(&'a str),
|
||||
}
|
||||
|
||||
/// An empty file used for creating a null source writer and measuring line
|
||||
/// metrics for various code layouts.
|
||||
pub struct NullFile;
|
||||
impl Write for NullFile {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
Ok(buf.len())
|
||||
}
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// A utility wrapper to write unbuffered data and correctly adjust positions.
|
||||
struct InnerWriter<'a, 'b: 'a, F: 'a + Write>(&'a mut SourceWriter<'b, F>);
|
||||
|
||||
@ -66,7 +54,7 @@ pub struct SourceWriter<'a, F: Write> {
|
||||
max_line_length: usize,
|
||||
}
|
||||
|
||||
pub type MeasureWriter<'a> = SourceWriter<'a, NullFile>;
|
||||
pub type MeasureWriter<'a> = SourceWriter<'a, &'a mut Vec<u8>>;
|
||||
|
||||
impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
pub fn new(out: F, bindings: &'a Bindings) -> Self {
|
||||
@ -87,23 +75,39 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
||||
|
||||
/// Takes a function that writes source and returns the maximum line length
|
||||
/// written.
|
||||
pub fn measure<T>(&self, func: T) -> usize
|
||||
pub fn try_write<T>(&mut self, func: T, max_line_length: usize) -> bool
|
||||
where
|
||||
T: Fn(&mut MeasureWriter),
|
||||
{
|
||||
let mut measurer = SourceWriter {
|
||||
out: NullFile,
|
||||
bindings: self.bindings,
|
||||
spaces: self.spaces.clone(),
|
||||
line_started: self.line_started,
|
||||
line_length: self.line_length,
|
||||
line_number: self.line_number,
|
||||
max_line_length: self.line_length,
|
||||
if self.line_length > max_line_length {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
let line_length = {
|
||||
let mut measurer = SourceWriter {
|
||||
out: &mut buffer,
|
||||
bindings: self.bindings,
|
||||
spaces: self.spaces.clone(),
|
||||
line_started: self.line_started,
|
||||
line_length: self.line_length,
|
||||
line_number: self.line_number,
|
||||
max_line_length: self.line_length,
|
||||
};
|
||||
|
||||
func(&mut measurer);
|
||||
|
||||
measurer.max_line_length
|
||||
};
|
||||
|
||||
func(&mut measurer);
|
||||
|
||||
measurer.max_line_length
|
||||
if line_length > max_line_length {
|
||||
return false;
|
||||
}
|
||||
// We don't want the extra alignment, it's already accounted for by the
|
||||
// measurer.
|
||||
self.line_started = true;
|
||||
InnerWriter(self).write_all(&buffer).unwrap();
|
||||
true
|
||||
}
|
||||
|
||||
fn spaces(&self) -> usize {
|
||||
|
Loading…
x
Reference in New Issue
Block a user