net-wire 0.1.0

Allocation-free no_std wire views and codecs for network protocols.
Documentation
use net_wire::ipv4::{
    Ipv4Address, Ipv4PacketBuildError, Ipv4PacketBuilder, Ipv4PacketMut, Ipv4Protocol,
};

fn complete<'a>(
    b: &'a mut [u8],
    options: &[u8],
) -> Result<Ipv4PacketMut<'a>, Ipv4PacketBuildError> {
    Ipv4PacketBuilder::new(b, 4)
        .source(Ipv4Address::new([192, 0, 2, 1]))
        .destination(Ipv4Address::new([198, 51, 100, 2]))
        .protocol(Ipv4Protocol::new(0xfd))
        .ttl(60)
        .identification(0x1234)
        .flags_fragment_offset(0x2005)
        .dscp_ecn(0xab)
        .options(options)
        .build()
}
fn built_from_local(buffer: &mut [u8]) -> Ipv4PacketMut<'_> {
    let options = [1, 2, 3, 4];
    complete(buffer, &options).unwrap()
}
#[test]
fn builder_is_exact_and_errors_atomic() {
    let mut b = [0xa5; 31];
    let p = built_from_local(&mut b);
    assert_eq!(
        p.as_bytes(),
        &[
            0x46, 0xab, 0, 28, 0x12, 0x34, 0x20, 5, 60, 0xfd, 0x59, 0xc4, 192, 0, 2, 1, 198, 51,
            100, 2, 1, 2, 3, 4, 0xa5, 0xa5, 0xa5, 0xa5,
        ]
    );
    assert_eq!(&b[24..], &[0xa5; 7]);
    macro_rules! e {
        ($x:expr,$want:expr) => {{
            let mut b = [0xa5; 64];
            let old = b;
            assert_eq!($x(&mut b), Err($want));
            assert_eq!(b, old)
        }};
    }
    fn m1(b: &mut [u8]) -> Result<Ipv4PacketMut<'_>, Ipv4PacketBuildError> {
        Ipv4PacketBuilder::new(b, 0).build()
    }
    fn m2(b: &mut [u8]) -> Result<Ipv4PacketMut<'_>, Ipv4PacketBuildError> {
        Ipv4PacketBuilder::new(b, 0)
            .source(Ipv4Address::new([1; 4]))
            .build()
    }
    fn m3(b: &mut [u8]) -> Result<Ipv4PacketMut<'_>, Ipv4PacketBuildError> {
        Ipv4PacketBuilder::new(b, 0)
            .source(Ipv4Address::new([1; 4]))
            .destination(Ipv4Address::new([2; 4]))
            .build()
    }
    fn m4(b: &mut [u8]) -> Result<Ipv4PacketMut<'_>, Ipv4PacketBuildError> {
        Ipv4PacketBuilder::new(b, 0)
            .source(Ipv4Address::new([1; 4]))
            .destination(Ipv4Address::new([2; 4]))
            .protocol(Ipv4Protocol::new(1))
            .build()
    }
    e!(m1, Ipv4PacketBuildError::MissingSource);
    e!(m2, Ipv4PacketBuildError::MissingDestination);
    e!(m3, Ipv4PacketBuildError::MissingProtocol);
    e!(m4, Ipv4PacketBuildError::MissingTtl);
    let mut b = [0xa5; 64];
    let old = b;
    assert_eq!(
        complete(&mut b, &[1, 2, 3]).map(|_| ()),
        Err(Ipv4PacketBuildError::InvalidOptionsLength)
    );
    assert_eq!(b, old);
    let mut b = [0xa5; 64];
    let old = b;
    assert_eq!(
        complete(&mut b, &[0; 44]).map(|_| ()),
        Err(Ipv4PacketBuildError::InvalidOptionsLength)
    );
    assert_eq!(b, old);
    let mut b = [0xa5; 64];
    let old = b;
    assert_eq!(
        Ipv4PacketBuilder::new(&mut b, 0)
            .source(Ipv4Address::new([1; 4]))
            .destination(Ipv4Address::new([2; 4]))
            .protocol(Ipv4Protocol::new(1))
            .ttl(1)
            .flags_fragment_offset(0x8000)
            .build(),
        Err(Ipv4PacketBuildError::ReservedFlagSet)
    );
    assert_eq!(b, old);
    let mut b = [0xa5; 64];
    let old = b;
    assert_eq!(
        Ipv4PacketBuilder::new(&mut b, usize::MAX)
            .source(Ipv4Address::new([1; 4]))
            .destination(Ipv4Address::new([2; 4]))
            .protocol(Ipv4Protocol::new(1))
            .ttl(1)
            .build(),
        Err(Ipv4PacketBuildError::TotalLengthTooLarge)
    );
    assert_eq!(b, old);
    let mut b = [0xa5; 64];
    let old = b;
    assert_eq!(
        Ipv4PacketBuilder::new(&mut b, 65_516)
            .source(Ipv4Address::new([1; 4]))
            .destination(Ipv4Address::new([2; 4]))
            .protocol(Ipv4Protocol::new(1))
            .ttl(1)
            .build(),
        Err(Ipv4PacketBuildError::TotalLengthTooLarge)
    );
    assert_eq!(b, old);
    let mut b = [0xa5; 23];
    let old = b;
    assert_eq!(
        complete(&mut b, &[]).map(|_| ()),
        Err(Ipv4PacketBuildError::BufferTooShort {
            required: 24,
            available: 23
        })
    );
    assert_eq!(b, old);
}