use std::io; use smallvec::{Array, SmallVec}; pub trait ReadExt: io::Read { fn read_max(&mut self, mut buf: &mut [u8]) -> io::Result { let start_len = buf.len(); while !buf.is_empty() { match self.read(buf) { Ok(0) => break, Ok(n) => { let tmp = buf; buf = &mut tmp[n..]; } Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} Err(e) => return Err(e), } } Ok(start_len - buf.len()) } } impl ReadExt for T { } // TODO: It would be nice if we could somehow have one trait that could give us // either SmallVec or Vec. pub trait IntoCollection { fn into_collection>(self) -> SmallVec; fn mapped U, A: Array>(self, f: F) -> SmallVec; } impl IntoCollection for T { #[inline] fn into_collection>(self) -> SmallVec { let mut vec = SmallVec::new(); vec.push(self); vec } #[inline(always)] fn mapped U, A: Array>(self, mut f: F) -> SmallVec { f(self).into_collection() } } impl IntoCollection for Vec { #[inline(always)] fn into_collection>(self) -> SmallVec { SmallVec::from_vec(self) } #[inline] fn mapped U, A: Array>(self, mut f: F) -> SmallVec { self.into_iter().map(|item| f(item)).collect() } } macro_rules! impl_for_slice { ($($size:tt)*) => ( impl<'a, T: Clone> IntoCollection for &'a [T $($size)*] { #[inline(always)] fn into_collection>(self) -> SmallVec { self.iter().cloned().collect() } #[inline] fn mapped U, A: Array>(self, mut f: F) -> SmallVec { self.iter().cloned().map(|item| f(item)).collect() } } ) } impl_for_slice!(); impl_for_slice!(; 1); impl_for_slice!(; 2); impl_for_slice!(; 3); impl_for_slice!(; 4); impl_for_slice!(; 5); impl_for_slice!(; 6); impl_for_slice!(; 7); impl_for_slice!(; 8); impl_for_slice!(; 9); impl_for_slice!(; 10);