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::Vertical => write_vertical(out, config, args),
|
||||||
Layout::Horizontal => write_horizontal(out, config, args),
|
Layout::Horizontal => write_horizontal(out, config, args),
|
||||||
Layout::Auto => {
|
Layout::Auto => {
|
||||||
if out.line_length_for_align()
|
if !out.try_write(
|
||||||
+ out.measure(|out| write_horizontal(out, config, args))
|
|out| write_horizontal(out, config, args),
|
||||||
> config.line_length
|
config.line_length,
|
||||||
{
|
) {
|
||||||
write_vertical(out, config, args)
|
write_vertical(out, config, args)
|
||||||
} else {
|
|
||||||
write_horizontal(out, config, args)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,14 +304,14 @@ impl Source for Function {
|
|||||||
condition.write_after(config, out);
|
condition.write_after(config, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
let option_1 = out.measure(|out| write_1(self, config, out));
|
match config.function.args {
|
||||||
|
Layout::Horizontal => write_1(self, config, out),
|
||||||
if (config.function.args == Layout::Auto && option_1 <= config.line_length)
|
Layout::Vertical => write_2(self, config, out),
|
||||||
|| config.function.args == Layout::Horizontal
|
Layout::Auto => {
|
||||||
{
|
if !out.try_write(|out| write_1(self, config, out), config.line_length) {
|
||||||
write_1(self, config, out);
|
write_2(self, config, out)
|
||||||
} else {
|
}
|
||||||
write_2(self, config, out);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,6 @@ pub enum ListType<'a> {
|
|||||||
Cap(&'a str),
|
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.
|
/// A utility wrapper to write unbuffered data and correctly adjust positions.
|
||||||
struct InnerWriter<'a, 'b: 'a, F: 'a + Write>(&'a mut SourceWriter<'b, F>);
|
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,
|
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> {
|
impl<'a, F: Write> SourceWriter<'a, F> {
|
||||||
pub fn new(out: F, bindings: &'a Bindings) -> Self {
|
pub fn new(out: F, bindings: &'a Bindings) -> Self {
|
||||||
@ -87,12 +75,18 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
|||||||
|
|
||||||
/// Takes a function that writes source and returns the maximum line length
|
/// Takes a function that writes source and returns the maximum line length
|
||||||
/// written.
|
/// written.
|
||||||
pub fn measure<T>(&self, func: T) -> usize
|
pub fn try_write<T>(&mut self, func: T, max_line_length: usize) -> bool
|
||||||
where
|
where
|
||||||
T: Fn(&mut MeasureWriter),
|
T: Fn(&mut MeasureWriter),
|
||||||
{
|
{
|
||||||
|
if self.line_length > max_line_length {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
let line_length = {
|
||||||
let mut measurer = SourceWriter {
|
let mut measurer = SourceWriter {
|
||||||
out: NullFile,
|
out: &mut buffer,
|
||||||
bindings: self.bindings,
|
bindings: self.bindings,
|
||||||
spaces: self.spaces.clone(),
|
spaces: self.spaces.clone(),
|
||||||
line_started: self.line_started,
|
line_started: self.line_started,
|
||||||
@ -104,6 +98,16 @@ impl<'a, F: Write> SourceWriter<'a, F> {
|
|||||||
func(&mut measurer);
|
func(&mut measurer);
|
||||||
|
|
||||||
measurer.max_line_length
|
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 {
|
fn spaces(&self) -> usize {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user