Repository: BurntSushi/byteorder (language: rust)

Issue:
Add a version using new `io` module
As I understand, the purpose of this crate is to prepare for a world where we no longer have the endian-writing/reading functions on Reader and Writer.  As someone that that uses those functions a lot, I would like to prepare my crates (namely [bincode](https://github.com/TyOverby/bincode)) for the new `io` crate.  I'd be willing to help do the port if you are interested.



Discussion / hints:
You should be able to use `byteorder` today with minimal changes. e.g., replace

```
self.reader.read_be_i64().map_err(wrap_io)
```

with

```
self.reader.read_i64::<BigEndian>().map_err(wrap_io)
```

You'll need to import `ReaderBytesExt` and `BigEndian` from `byteorder`.

Also, I'm on IRC (nick: `burntsushi`). Ping me. :-)

But `byteorder` still expects the reader to be `old_io::Reader` right?  

Oh! I see what you meant now. Yes. Currently using `old_io::Reader`. I think the transition to the new `io::Read` will be very easy because I explicitly did not use any of the extension methods that are going to get removed (I think).

If you want to start the port, that's fine with me. I probably don't want to merge to master until everything is fully baked in `std` though. Not sure when that's happening? I guess before the beta?

Sounds good.  How about a separate branch that tracks _new_ `io`?  I'll get started on the transition today or tomorrow.

Perfect. :-)


Fix patch:
diff --git a/README.md b/README.md
index 19328a8..99ba507 100644
--- a/README.md
+++ b/README.md
@@ -25,22 +25,22 @@ updated.  Add is to your `Cargo.toml` like so:
 byteorder = "*"
 ```
 
-If you want to augment existing `Reader` and `Writer` types, then import the
+If you want to augment existing `Read` and `Write` types, then import the
 extension methods like so:
 
 ```rust
 extern crate byteorder;
 
-use byteorder::{ReaderBytesExt, WriterBytesExt, BigEndian, LittleEndian};
+use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
 ```
 
 For example:
 
 ```rust
-use std::old_io::MemReader;
+use std::io::Cursor;
 use byteorder::{BigEndian, ReaderBytesExt};
 
-let mut rdr = MemReader::new(vec![2, 5, 3, 0]);
+let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
 // Note that we use type parameters to indicate which kind of byte order
 // we want!
 assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
diff --git a/src/lib.rs b/src/lib.rs
index 16c3390..44c831a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,35 +2,32 @@
 This crate provides convenience methods for encoding and decoding numbers
 in either big-endian or little-endian order.
 
-**Future plans:** Currently, this crate works with `std::old_io`. Once the
-new `std::io` crate is done, this crate will migrate to it.
-
 The organization of the crate is pretty simple. A trait, `ByteOrder`, specifies
 byte conversion methods for each type of number in Rust (sans numbers that have
 a platform dependent size like `usize` and `isize`). Two types, `BigEndian`
-and `LittleEndian` implement these methods. Finally, `ReaderBytesExt` and
-`WriterBytesExt` provide convenience methods available to all types that
+and `LittleEndian` implement these methods. Finally, `ReadBytesExt` and
+`WriteBytesExt` provide convenience methods available to all types that
 implement `Reader` and `Writer`.
 
 # Examples
 
-Read unsigned 16 bit big-endian integers from a `Reader`:
+Read unsigned 16 bit big-endian integers from a `Read`:
 
 ```rust
-use std::old_io::MemReader;
-use byteorder::{BigEndian, ReaderBytesExt};
+use std::io::Cursor;
+use byteorder::{BigEndian, ReadBytesExt};
 
-let mut rdr = MemReader::new(vec![2, 5, 3, 0]);
+let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
 // Note that we use type parameters to indicate which kind of byte order
 // we want!
 assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
 assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
 ```
 
-Write unsigned 16 bit little-endian integers to a `Writer`:
+Write unsigned 16 bit little-endian integers to a `Write`:
 
 ```rust
-use byteorder::{LittleEndian, WriterBytesExt};
+use byteorder::{LittleEndian, WriteBytesExt};
 
 let mut wtr = vec![];
 wtr.write_u16::<LittleEndian>(517).unwrap();
@@ -45,20 +42,12 @@ assert_eq!(wtr, vec![5, 2, 0, 3]);
 #![deny(missing_docs)]
 
 #![allow(unused_features)] // for `rand` while testing
+
 #![feature(core, io, test)]
 
-use std::old_io::IoResult;
+use std::io;
 use std::mem::transmute;
 
-// A trivial logging macro. No reason to pull in `log`, which has become
-// difficult to use in tests.
-macro_rules! lg {
-    ($($arg:tt)*) => ({
-        let _ = ::std::old_io::stderr().write_str(&*format!($($arg)*));
-        let _ = ::std::old_io::stderr().write_str("\n");
-    });
-}
-
 /// ByteOrder describes types that can serialize integers as bytes.
 ///
 /// Note that `Self` does not appear anywhere in this trait's definition!
@@ -191,7 +180,7 @@ pub trait ByteOrder {
     }
 }
 
-/// Extends `Reader` with methods for reading numbers.
+/// Extends `Read` with methods for reading numbers.
 ///
 /// Most of the methods defined here have an unconstrained type parameter that
 /// must be explicitly instantiated. Typically, it is instantiated with either
@@ -199,22 +188,22 @@ pub trait ByteOrder {
 ///
 /// # Examples
 ///
-/// Read unsigned 16 bit big-endian integers from a `Reader`:
+/// Read unsigned 16 bit big-endian integers from a `Read`:
 ///
 /// ```rust
-/// use std::old_io::MemReader;
-/// use byteorder::{BigEndian, ReaderBytesExt};
+/// use std::io::Cursor;
+/// use byteorder::{BigEndian, ReadBytesExt};
 ///
-/// let mut rdr = MemReader::new(vec![2, 5, 3, 0]);
+/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
 /// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
 /// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
 /// ```
-pub trait ReaderBytesExt: Reader + Sized {
+pub trait ReadBytesExt: io::Read + Sized {
     /// Reads an unsigned 8 bit integer from the underlying reader.
     ///
     /// Note that since this reads a single byte, no byte order conversions
     /// are used. It is included for completeness.
-    fn read_u8(&mut self) -> IoResult<u8> {
+    fn read_u8(&mut self) -> io::Result<u8> {
         let mut buf = [0; 1];
         try!(read_full(self, &mut buf));
         Ok(buf[0])
@@ -224,49 +213,49 @@ pub trait ReaderBytesExt: Reader + Sized {
     ///
     /// Note that since this reads a single byte, no byte order conversions
     /// are used. It is included for completeness.
-    fn read_i8(&mut self) -> IoResult<i8> {
+    fn read_i8(&mut self) -> io::Result<i8> {
         let mut buf = [0; 1];
         try!(read_full(self, &mut buf));
         Ok(buf[0] as i8)
     }
 
     /// Reads an unsigned 16 bit integer from the underlying reader.
-    fn read_u16<T: ByteOrder>(&mut self) -> IoResult<u16> {
+    fn read_u16<T: ByteOrder>(&mut self) -> io::Result<u16> {
         let mut buf = [0; 2];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_u16(&buf))
     }
 
     /// Reads a signed 16 bit integer from the underlying reader.
-    fn read_i16<T: ByteOrder>(&mut self) -> IoResult<i16> {
+    fn read_i16<T: ByteOrder>(&mut self) -> io::Result<i16> {
         let mut buf = [0; 2];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_i16(&buf))
     }
 
     /// Reads an unsigned 32 bit integer from the underlying reader.
-    fn read_u32<T: ByteOrder>(&mut self) -> IoResult<u32> {
+    fn read_u32<T: ByteOrder>(&mut self) -> io::Result<u32> {
         let mut buf = [0; 4];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_u32(&buf))
     }
 
     /// Reads a signed 32 bit integer from the underlying reader.
-    fn read_i32<T: ByteOrder>(&mut self) -> IoResult<i32> {
+    fn read_i32<T: ByteOrder>(&mut self) -> io::Result<i32> {
         let mut buf = [0; 4];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_i32(&buf))
     }
 
     /// Reads an unsigned 64 bit integer from the underlying reader.
-    fn read_u64<T: ByteOrder>(&mut self) -> IoResult<u64> {
+    fn read_u64<T: ByteOrder>(&mut self) -> io::Result<u64> {
         let mut buf = [0; 8];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_u64(&buf))
     }
 
     /// Reads a signed 64 bit integer from the underlying reader.
-    fn read_i64<T: ByteOrder>(&mut self) -> IoResult<i64> {
+    fn read_i64<T: ByteOrder>(&mut self) -> io::Result<i64> {
         let mut buf = [0; 8];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_i64(&buf))
@@ -274,7 +263,7 @@ pub trait ReaderBytesExt: Reader + Sized {
 
     /// Reads a IEEE754 single-precision (4 bytes) floating point number from
     /// the underlying reader.
-    fn read_f32<T: ByteOrder>(&mut self) -> IoResult<f32> {
+    fn read_f32<T: ByteOrder>(&mut self) -> io::Result<f32> {
         let mut buf = [0; 4];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_f32(&buf))
@@ -282,18 +271,18 @@ pub trait ReaderBytesExt: Reader + Sized {
 
     /// Reads a IEEE754 double-precision (8 bytes) floating point number from
     /// the underlying reader.
-    fn read_f64<T: ByteOrder>(&mut self) -> IoResult<f64> {
+    fn read_f64<T: ByteOrder>(&mut self) -> io::Result<f64> {
         let mut buf = [0; 8];
         try!(read_full(self, &mut buf));
         Ok(<T as ByteOrder>::read_f64(&buf))
     }
 }
 
-/// All types that implement `Reader` get methods defined in `ReaderBytesExt`
+/// All types that implement `Read` get methods defined in `ReadBytesExt`
 /// for free.
-impl<R: Reader> ReaderBytesExt for R {}
+impl<R: io::Read> ReadBytesExt for R {}
 
-fn read_full<R: Reader>(rdr: &mut R, buf: &mut [u8]) -> IoResult<()> {
+fn read_full<R: io::Read>(rdr: &mut R, buf: &mut [u8]) -> io::Result<()> {
     let mut n = 0us;
     while n < buf.len() {
         n += try!(rdr.read(&mut buf[n..]));
@@ -301,7 +290,7 @@ fn read_full<R: Reader>(rdr: &mut R, buf: &mut [u8]) -> IoResult<()> {
     Ok(())
 }
 
-/// Extends `Writer` with methods for writing numbers.
+/// Extends `Write` with methods for writing numbers.
 ///
 /// Most of the methods defined here have an unconstrained type parameter that
 /// must be explicitly instantiated. Typically, it is instantiated with either
@@ -309,22 +298,22 @@ fn read_full<R: Reader>(rdr: &mut R, buf: &mut [u8]) -> IoResult<()> {
 ///
 /// # Examples
 ///
-/// Write unsigned 16 bit big-endian integers to a `Writer`:
+/// Write unsigned 16 bit big-endian integers to a `Write`:
 ///
 /// ```rust
-/// use byteorder::{BigEndian, WriterBytesExt};
+/// use byteorder::{BigEndian, WriteBytesExt};
 ///
 /// let mut wtr = vec![];
 /// wtr.write_u16::<BigEndian>(517).unwrap();
 /// wtr.write_u16::<BigEndian>(768).unwrap();
 /// assert_eq!(wtr, vec![2, 5, 3, 0]);
 /// ```
-pub trait WriterBytesExt: Writer + Sized {
+pub trait WriteBytesExt: io::Write + Sized {
     /// Writes an unsigned 8 bit integer to the underlying writer.
     ///
     /// Note that since this writes a single byte, no byte order conversions
     /// are used. It is included for completeness.
-    fn write_u8(&mut self, n: u8) -> IoResult<()> {
+    fn write_u8(&mut self, n: u8) -> io::Result<()> {
         self.write_all(&[n])
     }
 
@@ -332,47 +321,47 @@ pub trait WriterBytesExt: Writer + Sized {
     ///
     /// Note that since this writes a single byte, no byte order conversions
     /// are used. It is included for completeness.
-    fn write_i8(&mut self, n: i8) -> IoResult<()> {
+    fn write_i8(&mut self, n: i8) -> io::Result<()> {
         self.write_all(&[n as u8])
     }
 
     /// Writes an unsigned 16 bit integer to the underlying writer.
-    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> IoResult<()> {
+    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> io::Result<()> {
         let mut buf = [0; 2];
         <T as ByteOrder>::write_u16(&mut buf, n);
         self.write_all(&buf)
     }
 
     /// Writes a signed 16 bit integer to the underlying writer.
-    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> IoResult<()> {
+    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> io::Result<()> {
         let mut buf = [0; 2];
         <T as ByteOrder>::write_i16(&mut buf, n);
         self.write_all(&buf)
     }
 
     /// Writes an unsigned 32 bit integer to the underlying writer.
-    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> IoResult<()> {
+    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> io::Result<()> {
         let mut buf = [0; 4];
         <T as ByteOrder>::write_u32(&mut buf, n);
         self.write_all(&buf)
     }
 
     /// Writes a signed 32 bit integer to the underlying writer.
-    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> IoResult<()> {
+    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> io::Result<()> {
         let mut buf = [0; 4];
         <T as ByteOrder>::write_i32(&mut buf, n);
         self.write_all(&buf)
     }
 
     /// Writes an unsigned 64 bit integer to the underlying writer.
-    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> IoResult<()> {
+    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> io::Result<()> {
         let mut buf = [0; 8];
         <T as ByteOrder>::write_u64(&mut buf, n);
         self.write_all(&buf)
     }
 
     /// Writes a signed 64 bit integer to the underlying writer.
-    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> IoResult<()> {
+    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> io::Result<()> {
         let mut buf = [0; 8];
         <T as ByteOrder>::write_i64(&mut buf, n);
         self.write_all(&buf)
@@ -380,7 +369,7 @@ pub trait WriterBytesExt: Writer + Sized {
 
     /// Writes a IEEE754 single-precision (4 bytes) floating point number to
     /// the underlying writer.
-    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> IoResult<()> {
+    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> io::Result<()> {
         let mut buf = [0; 4];
         <T as ByteOrder>::write_f32(&mut buf, n);
         self.write_all(&buf)
@@ -388,16 +377,16 @@ pub trait WriterBytesExt: Writer + Sized {
 
     /// Writes a IEEE754 double-precision (8 bytes) floating point number to
     /// the underlying writer.
-    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> IoResult<()> {
+    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> io::Result<()> {
         let mut buf = [0; 8];
         <T as ByteOrder>::write_f64(&mut buf, n);
         self.write_all(&buf)
     }
 }
 
-/// All types that implement `Writer` get methods defined in `WriterBytesExt`
+/// All types that implement `Write` get methods defined in `WriteBytesExt`
 /// for free.
-impl<W: Writer> WriterBytesExt for W {}
+impl<W: io::Write> WriteBytesExt for W {}
 
 /// Defines big-endian serialization.
 ///
@@ -553,9 +542,9 @@ mod test {
         ($name:ident, $ty_int:ident,
          $max:ident, $read:ident, $write:ident) => (
             mod $name {
-                use std::old_io::MemReader;
+                use std::io::Cursor;
                 use std::$ty_int;
-                use {ReaderBytesExt, WriterBytesExt, BigEndian, LittleEndian};
+                use {ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
                 use super::qc_sized;
 
                 #[test]
@@ -563,7 +552,7 @@ mod test {
                     fn prop(n: $ty_int) -> bool {
                         let mut wtr = vec![];
                         wtr.$write::<BigEndian>(n).unwrap();
-                        let mut rdr = MemReader::new(wtr);
+                        let mut rdr = Cursor::new(wtr);
                         n == rdr.$read::<BigEndian>().unwrap()
                     }
                     qc_sized(prop as fn($ty_int) -> bool,
@@ -575,7 +564,7 @@ mod test {
                     fn prop(n: $ty_int) -> bool {
                         let mut wtr = vec![];
                         wtr.$write::<LittleEndian>(n).unwrap();
-                        let mut rdr = MemReader::new(wtr);
+                        let mut rdr = Cursor::new(wtr);
                         n == rdr.$read::<LittleEndian>().unwrap()
                     }
                     qc_sized(prop as fn($ty_int) -> bool,


Test patch: