Skip to content

Commit

Permalink
Major internal rework and version bump
Browse files Browse the repository at this point in the history
  • Loading branch information
Tazdevil971 committed Jul 13, 2019
1 parent e003b51 commit 5a3fc11
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 63 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bin_io"
version = "0.1.2"
version = "0.2.0"
authors = ["Davide Mor <tazdevil971@gmail.com>"]
edition = "2018"
description = "Framework for reading and writing to binary files"
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ facilities at the same time, with fewer code.
## Usage
Add `bin_io = "0.1"` to your Cargo.toml

## Big change in 0.2
In 0.2 `bin_io` had a massive change, it now uses
references while writing, and no longer needs an owned
copy. This meant that some things needed to change
from the last version, but everything should still
work fine (with minor code changes, `seq!` in particular),
so check out the documentation!

## Example
```rust
use std::io::Cursor;
Expand Down
18 changes: 13 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
//! a: 0x10, b: 0x20
//! };
//!
//! write(&mut cursor, my_thing.clone(), thing_parser())
//! write(&mut cursor, &my_thing, thing_parser())
//! .unwrap();
//!
//! cursor.set_position(0);
Expand All @@ -44,6 +44,14 @@
//!
//! assert_eq!(other_thing, my_thing);
//! ```
//! # Big change in 0.2
//! In 0.2 `bin_io` had a massive change, it now uses
//! references while writing, and no longer needs an owned
//! copy. This meant that some things needed to change
//! from the last version, but everything should still
//! work fine (with minor code changes, `seq!` in particular),
//! so check out the documentation!
//!
//! # `nom` or `bin_io`?
//! `bin_io` is at a very early stage of development, so
//! you might want to prefer `nom` over `bin_io` for its
Expand Down Expand Up @@ -83,8 +91,8 @@ pub trait ReadFn<R: Read, I>: Fn(&mut R) -> io::Result<I> { }
impl<R: Read, I, F: Fn(&mut R) -> io::Result<I>> ReadFn<R, I> for F { }

/// Trait representing a write closure.
pub trait WriteFn<W: Write, I>: Fn(&mut W, I) -> io::Result<()> { }
impl<W: Write, I, F: Fn(&mut W, I) -> io::Result<()>> WriteFn<W, I> for F { }
pub trait WriteFn<W: Write, I>: Fn(&mut W, &I) -> io::Result<()> { }
impl<W: Write, I, F: Fn(&mut W, &I) -> io::Result<()>> WriteFn<W, I> for F { }

/// Reads from a read/write tuple.
///
Expand Down Expand Up @@ -119,13 +127,13 @@ where R: Read, Rf: ReadFn<R, I>, Wf: WriteFn<WriteDummy, I> {
/// let vec = Vec::new();
/// let mut cursor = Cursor::new(vec);
///
/// let val = write(&mut cursor, 0x80, be_u8())
/// let val = write(&mut cursor, &0x80, be_u8())
/// .unwrap();
///
/// let vec = cursor.into_inner();
/// assert_eq!(vec[0], 0x80);
/// ```
pub fn write<W, Rf, Wf, I>(w: &mut W, i: I, f: (Rf, Wf))
pub fn write<W, Rf, Wf, I>(w: &mut W, i: &I, f: (Rf, Wf))
-> io::Result<()>
where W: Write, Rf: ReadFn<ReadDummy, I>, Wf: WriteFn<W, I> {
f.1(w, i)
Expand Down
52 changes: 44 additions & 8 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,43 @@
/// b1: be_u8 =>
/// )
/// ```
/// While reading variables used are owned copies of the
/// values, while writing the values are references to
/// those values, so it's necessary that you always use
/// either as_ref() or to_owned() to collapse the two
/// states into a reference or an owned copy.
/// ```
/// use std::io::Cursor;
/// use bin_io::{ seq, count, read };
/// use bin_io::numbers::{ be_u8, be_i16 };
///
/// #[derive(Debug, PartialEq, Eq)]
/// struct Foo {
/// a: Vec<i16>
/// }
///
/// /* Won't compile
/// let tuple = seq!(
/// Foo { a },
/// len: be_u8(), a.len() as _ =>
/// a: count(be_i16(), len as usize) =>
/// );
/// */
///
/// let tuple = seq!(
/// Foo { a },
/// len: be_u8(), a.len() as _ =>
/// a: count(be_i16(), len.to_owned() as usize) =>
/// );
///
/// let mut vec = vec![ 0x02, 0x00, 0x01, 0x00, 0x02 ];
/// let mut cursor = Cursor::new(&mut vec);
///
/// let foo = read(&mut cursor, tuple)
/// .unwrap();
///
/// assert_eq!(foo, Foo { a: vec![ 1, 2 ] });
/// ```
/// # Examples
/// ```
/// use std::io::Cursor;
Expand All @@ -40,7 +76,7 @@
/// a: be_u8() =>
/// b: le_u16() =>
/// skip(be_u16(), 1557) =>
/// c: count(be_i32(), b as usize) =>
/// c: count(be_i32(), b.to_owned() as usize) =>
/// d: null_utf16() =>
/// );
///
Expand Down Expand Up @@ -110,7 +146,7 @@
/// // Give the field a default value or some expression to initialize it
/// // Remember: this value is only used during writing and not reading
/// length: be_u8(), a.len() as u8 =>
/// a: count(be_i16(), length as _) =>
/// a: count(be_i16(), length.to_owned() as _) =>
/// );
///
/// let vec = vec![ 0x2, 0x0, 0x50, 0x0, 0x60 ];
Expand All @@ -129,7 +165,7 @@ macro_rules! seq {
$($field),*
}, r, $($rest)*)
},
|w: &mut _, v: _| {
|w: &mut _, v: &_| {
let $($ty)::* {
$($field),*
} = v;
Expand All @@ -144,7 +180,7 @@ macro_rules! seq {
$($field),*
), r, $($rest)*)
},
|w: &mut _, v: _| {
|w: &mut _, v: &_| {
let $($ty)::* (
$($field),*
) = v;
Expand All @@ -157,7 +193,7 @@ macro_rules! seq {
(|r: &mut _| {
$crate::seq!(__impl r $($ty)::*, r, $($rest)*)
},
|w: &mut _, v: _| {
|w: &mut _, v: &_| {
let $($ty)::* = v;
$crate::seq!(__impl w w, $($rest)*);
Ok(())
Expand All @@ -168,7 +204,7 @@ macro_rules! seq {
(|r: &mut _| {
$crate::seq!(__impl r (), r, $($rest)*)
},
|w: &mut _, v: _| {
|w: &mut _, v: &_| {
$crate::seq!(__impl w w, $($rest)*);
Ok(())
})
Expand Down Expand Up @@ -210,15 +246,15 @@ macro_rules! seq {

(__impl w $w:ident, $name:ident : $expr:expr, $def:expr => $($rest:tt)*) => {
{
let $name = $def;
let $name = &$def;
$crate::write($w, $name, $expr)?;
$crate::seq!(__impl w $w, $($rest)*);
}
};

(__impl w $w:ident, $expr:expr => $($rest:tt)*) => {
{
$crate::write($w, (), $expr)?;
$crate::write($w, &(), $expr)?;
$crate::seq!(__impl w $w, $($rest)*);
}
};
Expand Down
44 changes: 22 additions & 22 deletions src/numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//! let mut cursor = Cursor::new(vec);
//!
//! // Write a Little Endian f32
//! write(&mut cursor, 1.5, le_f32())
//! write(&mut cursor, &1.5, le_f32())
//! .unwrap();
//!
//! assert_eq!(cursor.get_ref(), &[ 0x00, 0x00, 0xc0, 0x3f ]);
Expand All @@ -36,34 +36,34 @@ macro_rules! auto_impl {

(|$r: &mut R|
$read,
|$w: &mut W, $v: $ty|
|$w: &mut W, $v: &$ty|
$write)
}
};
}

auto_impl!(be_u8, u8, r, w, v, r.read_u8(), w.write_u8(v));
auto_impl!(be_i8, i8, r, w, v, r.read_i8(), w.write_i8(v));
auto_impl!(le_u8, u8, r, w, v, r.read_u8(), w.write_u8(v));
auto_impl!(le_i8, i8, r, w, v, r.read_i8(), w.write_i8(v));
auto_impl!(be_u8, u8, r, w, v, r.read_u8(), w.write_u8(*v));
auto_impl!(be_i8, i8, r, w, v, r.read_i8(), w.write_i8(*v));
auto_impl!(le_u8, u8, r, w, v, r.read_u8(), w.write_u8(*v));
auto_impl!(le_i8, i8, r, w, v, r.read_i8(), w.write_i8(*v));

auto_impl!(be_u16, u16, r, w, v, r.read_u16::<BigEndian>(), w.write_u16::<BigEndian>(v));
auto_impl!(be_i16, i16, r, w, v, r.read_i16::<BigEndian>(), w.write_i16::<BigEndian>(v));
auto_impl!(le_u16, u16, r, w, v, r.read_u16::<LittleEndian>(), w.write_u16::<LittleEndian>(v));
auto_impl!(le_i16, i16, r, w, v, r.read_i16::<LittleEndian>(), w.write_i16::<LittleEndian>(v));
auto_impl!(be_u16, u16, r, w, v, r.read_u16::<BigEndian>(), w.write_u16::<BigEndian>(*v));
auto_impl!(be_i16, i16, r, w, v, r.read_i16::<BigEndian>(), w.write_i16::<BigEndian>(*v));
auto_impl!(le_u16, u16, r, w, v, r.read_u16::<LittleEndian>(), w.write_u16::<LittleEndian>(*v));
auto_impl!(le_i16, i16, r, w, v, r.read_i16::<LittleEndian>(), w.write_i16::<LittleEndian>(*v));

auto_impl!(be_u32, u32, r, w, v, r.read_u32::<BigEndian>(), w.write_u32::<BigEndian>(v));
auto_impl!(be_i32, i32, r, w, v, r.read_i32::<BigEndian>(), w.write_i32::<BigEndian>(v));
auto_impl!(le_u32, u32, r, w, v, r.read_u32::<LittleEndian>(), w.write_u32::<LittleEndian>(v));
auto_impl!(le_i32, i32, r, w, v, r.read_i32::<LittleEndian>(), w.write_i32::<LittleEndian>(v));
auto_impl!(be_u32, u32, r, w, v, r.read_u32::<BigEndian>(), w.write_u32::<BigEndian>(*v));
auto_impl!(be_i32, i32, r, w, v, r.read_i32::<BigEndian>(), w.write_i32::<BigEndian>(*v));
auto_impl!(le_u32, u32, r, w, v, r.read_u32::<LittleEndian>(), w.write_u32::<LittleEndian>(*v));
auto_impl!(le_i32, i32, r, w, v, r.read_i32::<LittleEndian>(), w.write_i32::<LittleEndian>(*v));

auto_impl!(be_u64, u64, r, w, v, r.read_u64::<BigEndian>(), w.write_u64::<BigEndian>(v));
auto_impl!(be_i64, i64, r, w, v, r.read_i64::<BigEndian>(), w.write_i64::<BigEndian>(v));
auto_impl!(le_u64, u64, r, w, v, r.read_u64::<LittleEndian>(), w.write_u64::<LittleEndian>(v));
auto_impl!(le_i64, i64, r, w, v, r.read_i64::<LittleEndian>(), w.write_i64::<LittleEndian>(v));
auto_impl!(be_u64, u64, r, w, v, r.read_u64::<BigEndian>(), w.write_u64::<BigEndian>(*v));
auto_impl!(be_i64, i64, r, w, v, r.read_i64::<BigEndian>(), w.write_i64::<BigEndian>(*v));
auto_impl!(le_u64, u64, r, w, v, r.read_u64::<LittleEndian>(), w.write_u64::<LittleEndian>(*v));
auto_impl!(le_i64, i64, r, w, v, r.read_i64::<LittleEndian>(), w.write_i64::<LittleEndian>(*v));

auto_impl!(be_f32, f32, r, w, v, r.read_f32::<BigEndian>(), w.write_f32::<BigEndian>(v));
auto_impl!(le_f32, f32, r, w, v, r.read_f32::<LittleEndian>(), w.write_f32::<LittleEndian>(v));
auto_impl!(be_f32, f32, r, w, v, r.read_f32::<BigEndian>(), w.write_f32::<BigEndian>(*v));
auto_impl!(le_f32, f32, r, w, v, r.read_f32::<LittleEndian>(), w.write_f32::<LittleEndian>(*v));

auto_impl!(be_f64, f64, r, w, v, r.read_f64::<BigEndian>(), w.write_f64::<BigEndian>(v));
auto_impl!(le_f64, f64, r, w, v, r.read_f64::<LittleEndian>(), w.write_f64::<LittleEndian>(v));
auto_impl!(be_f64, f64, r, w, v, r.read_f64::<BigEndian>(), w.write_f64::<BigEndian>(*v));
auto_impl!(le_f64, f64, r, w, v, r.read_f64::<LittleEndian>(), w.write_f64::<LittleEndian>(*v));
12 changes: 6 additions & 6 deletions src/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn null_ascii<R: Read, W: Write>()
false => Err(Error::from(BinError::CheckFail))
}
},
|w: &mut W, s: String| {
|w: &mut W, s: &String| {
match s.is_ascii() {
true => write(w, s, null_utf8()),
false => panic!("String is not ascii")
Expand Down Expand Up @@ -89,7 +89,7 @@ pub fn len_ascii<R: Read, W: Write>(len: usize)
false => Err(Error::from(BinError::CheckFail))
}
},
move |w: &mut W, s: String| {
move |w: &mut W, s: &String| {
match s.is_ascii() {
true => write(w, s, len_utf8(len)),
false => panic!("String is not ascii")
Expand Down Expand Up @@ -135,7 +135,7 @@ pub fn null_utf8<R: Read, W: Write>()
String::from_utf8(s)
.map_err(|e| Error::from(BinError::from(e)))
},
|w: &mut W, s: String| {
|w: &mut W, s: &String| {

w.write_all(&s.as_bytes()[..])
})
Expand Down Expand Up @@ -173,7 +173,7 @@ pub fn len_utf8<R: Read, W: Write>(len: usize)
String::from_utf8(s)
.map_err(|e| Error::from(BinError::from(e)))
},
move |w: &mut W, s: String| {
move |w: &mut W, s: &String| {

match s.len() == len {
true => w.write_all(&s.as_bytes()[..]),
Expand Down Expand Up @@ -214,7 +214,7 @@ pub fn null_utf16<R: Read, W: Write>()
String::from_utf16(&s[..])
.map_err(|e| Error::from(BinError::from(e)))
},
|w: &mut W, s: String| {
|w: &mut W, s: &String| {
for c in s.encode_utf16() {
w.write_u16::<BigEndian>(c)?;
}
Expand Down Expand Up @@ -252,7 +252,7 @@ pub fn len_utf16<R: Read, W: Write>(len: usize)
String::from_utf16(&s[..])
.map_err(|e| Error::from(BinError::from(e)))
},
move |w: &mut W, s: String| {
move |w: &mut W, s: &String| {
match s.len() == len {
true => {
for c in s.encode_utf16() {
Expand Down
Loading

0 comments on commit 5a3fc11

Please sign in to comment.