Rewrite path::Display to reduce unnecessary allocation

This commit is contained in:
Kevin Ballard 2014-02-07 19:45:48 -08:00
parent 086c0dd33f
commit 1d17c2129e
6 changed files with 24 additions and 50 deletions

View File

@ -442,9 +442,7 @@ fn check_error_patterns(props: &TestProps,
testfile: &Path,
ProcRes: &ProcRes) {
if props.error_patterns.is_empty() {
testfile.display().with_str(|s| {
fatal(~"no error pattern specified in " + s);
})
fatal(~"no error pattern specified in " + testfile.display().as_maybe_owned().as_slice());
}
if ProcRes.status.success() {

View File

@ -436,7 +436,7 @@ impl<'a> SourceCollector<'a> {
cur.push(p.filename().expect("source has no filename") + bytes!(".html"));
let mut w = BufferedWriter::new(if_ok!(File::create(&cur)));
let title = cur.filename_display().with_str(|s| format!("{} -- source", s));
let title = format!("{} -- source", cur.filename_display());
let page = layout::Page {
title: title,
ty: "source",

View File

@ -70,7 +70,7 @@ use fmt;
use iter::Iterator;
use option::{Option, None, Some};
use str;
use str::{OwnedStr, Str, StrSlice};
use str::{MaybeOwned, OwnedStr, Str, StrSlice, from_utf8_lossy};
use to_str::ToStr;
use vec;
use vec::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector};
@ -495,7 +495,7 @@ pub struct Display<'a, P> {
impl<'a, P: GenericPath> fmt::Show for Display<'a, P> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.with_str(|s| f.pad(s))
self.as_maybe_owned().as_slice().fmt(f)
}
}
@ -505,33 +505,25 @@ impl<'a, P: GenericPath> ToStr for Display<'a, P> {
/// If the path is not UTF-8, invalid sequences with be replaced with the
/// unicode replacement char. This involves allocation.
fn to_str(&self) -> ~str {
if self.filename {
match self.path.filename() {
None => ~"",
Some(v) => str::from_utf8_lossy(v).into_owned()
}
} else {
str::from_utf8_lossy(self.path.as_vec()).into_owned()
}
self.as_maybe_owned().into_owned()
}
}
impl<'a, P: GenericPath> Display<'a, P> {
/// Provides the path as a string to a closure
/// Returns the path as a possibly-owned string.
///
/// If the path is not UTF-8, invalid sequences will be replaced with the
/// unicode replacement char. This involves allocation.
#[inline]
pub fn with_str<T>(&self, f: |&str| -> T) -> T {
let opt = if self.filename { self.path.filename_str() }
else { self.path.as_str() };
match opt {
Some(s) => f(s),
None => {
let s = self.to_str();
f(s.as_slice())
pub fn as_maybe_owned(&self) -> MaybeOwned<'a> {
from_utf8_lossy(if self.filename {
match self.path.filename() {
None => &[],
Some(v) => v
}
}
} else {
self.path.as_vec()
})
}
}

View File

@ -564,24 +564,16 @@ mod tests {
macro_rules! t(
($path:expr, $exp:expr) => (
{
let mut called = false;
let path = Path::new($path);
path.display().with_str(|s| {
assert_eq!(s, $exp);
called = true;
});
assert!(called);
let mo = path.display().as_maybe_owned();
assert_eq!(mo.as_slice(), $exp);
}
);
($path:expr, $exp:expr, filename) => (
{
let mut called = false;
let path = Path::new($path);
path.filename_display().with_str(|s| {
assert_eq!(s, $exp);
called = true;
});
assert!(called);
let mo = path.filename_display().as_maybe_owned();
assert_eq!(mo.as_slice(), $exp);
}
)
)

View File

@ -1278,20 +1278,12 @@ mod tests {
let path = Path::new(b!("\\"));
assert_eq!(path.filename_display().to_str(), ~"");
let mut called = false;
let path = Path::new("foo");
path.display().with_str(|s| {
assert_eq!(s, "foo");
called = true;
});
assert!(called);
called = false;
let mo = path.display().as_maybe_owned();
assert_eq!(mo.as_slice(), "foo");
let path = Path::new(b!("\\"));
path.filename_display().with_str(|s| {
assert_eq!(s, "");
called = true;
});
assert!(called);
let mo = path.filename_display().as_maybe_owned();
assert_eq!(mo.as_slice(), "");
}
#[test]

View File

@ -4200,10 +4200,10 @@ impl Parser {
let mut err = ~"circular modules: ";
let len = included_mod_stack.get().len();
for p in included_mod_stack.get().slice(i, len).iter() {
p.display().with_str(|s| err.push_str(s));
err.push_str(p.display().as_maybe_owned().as_slice());
err.push_str(" -> ");
}
path.display().with_str(|s| err.push_str(s));
err.push_str(path.display().as_maybe_owned().as_slice());
self.span_fatal(id_sp, err);
}
None => ()