1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
/*! This crate provides a convenient way of reading and writing bytes to a buffer that implements the standard [`Read`] or [`Write`] traits. Supported std types include [`u8`], [`u16`], [`u32`], [`u64`], [`i8`], [`i16`], [`i32`] and [`i64`]. Reading and writing of these types is done using the [`byteorder`] crate. # Installation Add the following to your `Cargo.toml` file: ```toml [dependencies] bytestream = "0.4" ``` # Examples ```rust use std::io::{Cursor, Read, Result, Write}; use bytestream::*; #[derive(Debug, PartialEq)] pub struct Foo { bar: bool, baz: u32, } impl StreamReader for Foo { fn read_from<R: Read>(buffer: &mut R, order: ByteOrder) -> Result<Self> { Ok(Self { bar: bool::read_from(buffer, order)?, baz: u32::read_from(buffer, order)?, }) } } impl StreamWriter for Foo { fn write_to<W: Write>(&self, buffer: &mut W, order: ByteOrder) -> Result<()> { self.bar.write_to(buffer, order)?; self.baz.write_to(buffer, order)?; Ok(()) } } // Create a buffer that implements the `Write` trait let mut buffer = Vec::<u8>::new(); // Write some data to the buffer let foo = Foo { bar: true, baz: 37 }; foo.write_to(&mut buffer, ByteOrder::BigEndian).unwrap(); // Read the data back from the buffer // We wrap the buffer in a Cursor::<T> that implements the `Read` trait let mut cursor = Cursor::new(buffer); let other = Foo::read_from(&mut cursor, ByteOrder::BigEndian).unwrap(); assert_eq!(foo, other); ``` # Exclude streamable support for std types If you do not wish to include out-of-the-box support for std types, you can exclude the default feature in your `Cargo.toml` file: ```toml [dependencies] bytestream = { Version = "0.4", default-features = false } ``` Exluding the default feature will also remove the `byteorder` crate dependency. # Credits The inspiration from this crate came from the [`Stevenarella`] Minecraft client. [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html [`byteorder`]: https://github.com/BurntSushi/byteorder [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html [`u16`]: https://doc.rust-lang.org/std/primitive.u16.html [`u32`]: https://doc.rust-lang.org/std/primitive.u32.html [`u64`]: https://doc.rust-lang.org/std/primitive.u64.html [`i8`]: https://doc.rust-lang.org/std/primitive.i8.html [`i16`]: https://doc.rust-lang.org/std/primitive.i16.html [`i32`]: https://doc.rust-lang.org/std/primitive.i32.html [`i64`]: https://doc.rust-lang.org/std/primitive.i64.html [`Stevenarella`]: https://github.com/iceiix/stevenarella */ #![deny(missing_docs)] use std::io::{Read, Result, Write}; #[cfg(feature = "byteorder")] mod byteorder; #[cfg(feature = "byteorder")] pub use crate::byteorder::*; /// `ByteOrder` describes what order to write bytes to the buffer. #[derive(Copy, Clone)] pub enum ByteOrder { /// Represents big endian byte order (also called network endian). /// This is the default order if none is specified. BigEndian, /// Represents little endian byte order. LittleEndian, } /// The `StreamReader` trait allows for reading and writing /// bytes to and from a buffer. /// /// # Example /// /// ``` /// use std::io::{Read, Result, Write}; /// use bytestream::*; /// /// pub struct Foo { /// bar: bool, /// baz: u32, /// } /// /// impl StreamReader for Foo { /// fn read_from<R: Read>(buffer: &mut R, order: ByteOrder) -> Result<Self> { /// Ok(Self { /// bar: bool::read_from(buffer, order)?, /// baz: u32::read_from(buffer, order)?, /// }) /// } /// } /// ``` pub trait StreamReader: Sized { /// Reads something from the specified buffer using the specified byte order. fn read_from<R: Read>(buffer: &mut R, order: ByteOrder) -> Result<Self>; } /// The `StreamWriter` trait allows for reading and writing /// bytes to and from a buffer. /// /// # Example /// /// ``` /// use std::io::{Read, Result, Write}; /// use bytestream::*; /// /// pub struct Foo { /// bar: bool, /// baz: u32, /// } /// /// impl StreamWriter for Foo { /// fn write_to<W: Write>(&self, buffer: &mut W, order: ByteOrder) -> Result<()> { /// self.bar.write_to(buffer, order)?; /// self.baz.write_to(buffer, order)?; /// Ok(()) /// } /// } /// ``` pub trait StreamWriter: Sized { /// Writes something to the specified buffer using the specified byte order. fn write_to<W: Write>(&self, buffer: &mut W, order: ByteOrder) -> Result<()>; }