Auto merge of #27197 - nwin:generic-cursor-impl, r=alexcrichton
This is a revival of #23364. Github didn’t recognize my updated branch there. The cursor implementation now uses `AsRef` which means that fixed-sized array can now be used with `Cursor`. Besides that, the generic implementation simplifies the code as the macro can be avoided. The only drawback is, that specialized implementation for fixed-sized arrays are now ruled out unless [RFC#1210](https://github.com/rust-lang/rfcs/pull/1210) is accepted & implemented. `Box<[u8]>` cannot be used yet, but that should be mitigated by [implementing `AsRef` for `Box` and friends](https://internals.rust-lang.org/t/forward-implement-traits-on-smart-pointers-make-smart-pointers-more-transparent/2380/3). I will submit a separate PR for that later as it is an orthogonal issue.
This commit is contained in:
commit
11eda66df8
|
@ -192,12 +192,12 @@ impl<T> Cursor<T> {
|
|||
pub fn set_position(&mut self, pos: u64) { self.pos = pos; }
|
||||
}
|
||||
|
||||
macro_rules! seek {
|
||||
() => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> io::Seek for Cursor<T> where T: AsRef<[u8]> {
|
||||
fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
|
||||
let pos = match style {
|
||||
SeekFrom::Start(n) => { self.pos = n; return Ok(n) }
|
||||
SeekFrom::End(n) => self.inner.len() as i64 + n,
|
||||
SeekFrom::End(n) => self.inner.as_ref().len() as i64 + n,
|
||||
SeekFrom::Current(n) => self.pos as i64 + n,
|
||||
};
|
||||
|
||||
|
@ -209,50 +209,26 @@ macro_rules! seek {
|
|||
Ok(self.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); }
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); }
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl io::Seek for Cursor<Vec<u8>> { seek!(); }
|
||||
|
||||
macro_rules! read {
|
||||
() => {
|
||||
impl<T> Read for Cursor<T> where T: AsRef<[u8]> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let n = try!(Read::read(&mut try!(self.fill_buf()), buf));
|
||||
self.pos += n as u64;
|
||||
Ok(n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> Read for Cursor<&'a [u8]> { read!(); }
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> Read for Cursor<&'a mut [u8]> { read!(); }
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Read for Cursor<Vec<u8>> { read!(); }
|
||||
|
||||
macro_rules! buffer {
|
||||
() => {
|
||||
impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> {
|
||||
fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
||||
let amt = cmp::min(self.pos, self.inner.len() as u64);
|
||||
Ok(&self.inner[(amt as usize)..])
|
||||
let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
|
||||
Ok(&self.inner.as_ref()[(amt as usize)..])
|
||||
}
|
||||
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); }
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); }
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> Write for Cursor<&'a mut [u8]> {
|
||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
|
||||
|
|
Loading…
Reference in New Issue