pigeon 0.1.0

Utilities for efficient packing and unpacking of big-endian binary data
Documentation
use {
    pigeon::{Dump, FrameReader, FrameWriter, ShortStr},
    proptest::{prelude::*, test_runner::Config},
};

macro_rules! readwrite_single {
    ($name:ident, $t:ty) => {
        proptest! {
            #![proptest_config(Config::with_cases(300))]
            #[test]
            fn $name ( value in any::<$t>() ) {
                let mut buf = [0; 128];
                let mut writer = FrameWriter::new(&mut buf[..]);
                writer.write(value);
                let writer_pos = writer.position();
                let mut reader = FrameReader::new(&buf[..]);
                let value_read: $t = reader.read().unwrap();
                assert_eq!(value, value_read);
                let reader_pos = reader.position();
                assert_eq!(writer_pos, reader_pos);
                assert_eq!(writer_pos, Dump::size(&value));
            }
        }
    };
}

macro_rules! readwrite_all {
    ($($name:ident => $t:ty,)*) => {
        $(
            readwrite_single!($name, $t);
        )*
    };
}

readwrite_all!(
    readwrite_u8  => u8,
    readwrite_u16 => u16,
    readwrite_u32 => u32,
    readwrite_u64 => u64,

    readwrite_i8  => i8,
    readwrite_i16 => i16,
    readwrite_i32 => i32,
    readwrite_i64 => i64,

    readwrite_f32 => f32,
    readwrite_f64 => f64,

    readwrite_u8_u16_u32_u64 => (u8, u16, u32, u64),
    readwrite_u64_u32_u16_u8 => (u64, u32, u16, u8),

    readwrite_i8_i16_i32_i64 => (i8, i16, i32, i64),
    readwrite_i64_i32_i16_i8 => (i64, i32, i16, i8),
);

proptest! {
    #![proptest_config(Config::with_cases(300))]
    #[test]
    fn readwrite_shortstr(
        s in ".{1,255}",
    ) {
        if s.as_bytes().len() < 256 {
            let mut buf = [0; 257];
            let mut writer = FrameWriter::new(&mut buf[..]);
            writer.write(ShortStr(&s));
            let mut reader = FrameReader::new(&buf[..]);
            let ShortStr(s_read) = reader.read().unwrap();
            assert_eq!(s, s_read);
        }
    }
}

proptest! {
    #![proptest_config(Config::with_cases(300))]
    #[test]
    fn readwrite_shortstr_seq(
        sa in ".{1,255}",
        sb in ".{1,255}",
    ) {
        if sa.as_bytes().len() < 256 && sb.as_bytes().len() < 256 {
            let mut buf = [0; 514];
            let mut writer = FrameWriter::new(&mut buf[..]);
            writer.write(ShortStr(&sa));
            writer.write(ShortStr(&sb));
            let mut reader = FrameReader::new(&buf[..]);
            let ShortStr(sa_read) = reader.read().unwrap();
            let ShortStr(sb_read) = reader.read().unwrap();
            assert_eq!(sa, sa_read);
            assert_eq!(sb, sb_read);
        }
    }
}