1
Fork 0

auto merge of #13395 : Ryman/rust/bytecontainer_impl_container, r=alexcrichton

Also some minor cleanup in Path related to this.
This commit is contained in:
bors 2014-04-11 13:46:45 -07:00
commit ecc774f788
2 changed files with 32 additions and 46 deletions

View file

@ -158,7 +158,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
/// See individual Path impls for additional restrictions. /// See individual Path impls for additional restrictions.
#[inline] #[inline]
fn new<T: BytesContainer>(path: T) -> Self { fn new<T: BytesContainer>(path: T) -> Self {
assert!(!contains_nul(path.container_as_bytes())); assert!(!contains_nul(&path));
unsafe { GenericPathUnsafe::new_unchecked(path) } unsafe { GenericPathUnsafe::new_unchecked(path) }
} }
@ -166,7 +166,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
/// The resulting Path will always be normalized. /// The resulting Path will always be normalized.
#[inline] #[inline]
fn new_opt<T: BytesContainer>(path: T) -> Option<Self> { fn new_opt<T: BytesContainer>(path: T) -> Option<Self> {
if contains_nul(path.container_as_bytes()) { if contains_nul(&path) {
None None
} else { } else {
Some(unsafe { GenericPathUnsafe::new_unchecked(path) }) Some(unsafe { GenericPathUnsafe::new_unchecked(path) })
@ -274,7 +274,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
/// Fails the task if the filename contains a NUL. /// Fails the task if the filename contains a NUL.
#[inline] #[inline]
fn set_filename<T: BytesContainer>(&mut self, filename: T) { fn set_filename<T: BytesContainer>(&mut self, filename: T) {
assert!(!contains_nul(filename.container_as_bytes())); assert!(!contains_nul(&filename));
unsafe { self.set_filename_unchecked(filename) } unsafe { self.set_filename_unchecked(filename) }
} }
/// Replaces the extension with the given byte vector or string. /// Replaces the extension with the given byte vector or string.
@ -286,43 +286,30 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
/// ///
/// Fails the task if the extension contains a NUL. /// Fails the task if the extension contains a NUL.
fn set_extension<T: BytesContainer>(&mut self, extension: T) { fn set_extension<T: BytesContainer>(&mut self, extension: T) {
assert!(!contains_nul(extension.container_as_bytes())); assert!(!contains_nul(&extension));
// borrowck causes problems here too
let val = { let val = self.filename().and_then(|name| {
match self.filename() { let dot = '.' as u8;
None => None, let extlen = extension.container_as_bytes().len();
Some(name) => { match (name.rposition_elem(&dot), extlen) {
let dot = '.' as u8; (None, 0) | (Some(0), 0) => None,
match name.rposition_elem(&dot) { (Some(idx), 0) => Some(name.slice_to(idx).to_owned()),
None | Some(0) => { (idx, extlen) => {
if extension.container_as_bytes().is_empty() { let idx = match idx {
None None | Some(0) => name.len(),
} else { Some(val) => val
let mut v; };
let extension = extension.container_as_bytes();
v = slice::with_capacity(name.len() + extension.len() + 1); let mut v;
v.push_all(name); v = slice::with_capacity(idx + extlen + 1);
v.push(dot); v.push_all(name.slice_to(idx));
v.push_all(extension); v.push(dot);
Some(v) v.push_all(extension.container_as_bytes());
} Some(v)
}
Some(idx) => {
if extension.container_as_bytes().is_empty() {
Some(name.slice_to(idx).to_owned())
} else {
let mut v;
let extension = extension.container_as_bytes();
v = slice::with_capacity(idx + extension.len() + 1);
v.push_all(name.slice_to(idx+1));
v.push_all(extension);
Some(v)
}
}
}
} }
} }
}; });
match val { match val {
None => (), None => (),
Some(v) => unsafe { self.set_filename_unchecked(v) } Some(v) => unsafe { self.set_filename_unchecked(v) }
@ -376,7 +363,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
/// Fails the task if the path contains a NUL. /// Fails the task if the path contains a NUL.
#[inline] #[inline]
fn push<T: BytesContainer>(&mut self, path: T) { fn push<T: BytesContainer>(&mut self, path: T) {
assert!(!contains_nul(path.container_as_bytes())); assert!(!contains_nul(&path));
unsafe { self.push_unchecked(path) } unsafe { self.push_unchecked(path) }
} }
/// Pushes multiple paths (as byte vectors or strings) onto `self`. /// Pushes multiple paths (as byte vectors or strings) onto `self`.
@ -589,8 +576,8 @@ impl<'a> BytesContainer for str::MaybeOwned<'a> {
} }
#[inline(always)] #[inline(always)]
fn contains_nul(v: &[u8]) -> bool { fn contains_nul<T: BytesContainer>(v: &T) -> bool {
v.iter().any(|&x| x == 0) v.container_as_bytes().iter().any(|&x| x == 0)
} }
#[cfg(test)] #[cfg(test)]

View file

@ -306,14 +306,13 @@ impl GenericPathUnsafe for Path {
impl GenericPath for Path { impl GenericPath for Path {
#[inline] #[inline]
fn new_opt<T: BytesContainer>(path: T) -> Option<Path> { fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
let s = path.container_as_str(); match path.container_as_str() {
match s {
None => None, None => None,
Some(s) => { Some(ref s) => {
if contains_nul(s.as_bytes()) { if contains_nul(s) {
None None
} else { } else {
Some(unsafe { GenericPathUnsafe::new_unchecked(s) }) Some(unsafe { GenericPathUnsafe::new_unchecked(*s) })
} }
} }
} }