net-wire 0.1.0

Allocation-free no_std wire views and codecs for network protocols.
Documentation
use std::error::Error;
use std::iter::FusedIterator;

use net_wire::kcp::{KcpSegmentIter, KcpSegmentParseError, KcpSegments, KcpSegmentsParseError};

use super::fixtures::SEGMENT;

#[test]
fn sequences_are_strict_and_iterate_valid_prefix_once() {
    assert_eq!(
        KcpSegments::parse(&[]),
        Err(KcpSegmentsParseError::EmptySequence)
    );

    let mut concatenated = [0; 54];
    concatenated[..27].copy_from_slice(&SEGMENT);
    concatenated[27..].copy_from_slice(&SEGMENT);
    let sequence = KcpSegments::parse(&concatenated).unwrap();
    assert_eq!(sequence.as_bytes(), concatenated);
    assert_eq!(
        sequence
            .iter()
            .map(|segment| segment.unwrap().payload())
            .collect::<Vec<_>>(),
        vec![&[0xde, 0xad, 0xbe][..], &[0xde, 0xad, 0xbe][..]]
    );

    let mut partial_header = [0; 32];
    partial_header[..27].copy_from_slice(&SEGMENT);
    let trailing_error = KcpSegments::parse(&partial_header).unwrap_err();
    assert_eq!(
        trailing_error,
        KcpSegmentsParseError::Segment {
            offset: 27,
            error: KcpSegmentParseError::HeaderTruncated {
                required: 24,
                available: 5
            }
        }
    );
    assert_eq!(
        Error::source(&trailing_error).unwrap().to_string(),
        "KCP segment header is truncated: need 24 bytes, have 5"
    );

    let mut late_payload = [0; 56];
    late_payload[..27].copy_from_slice(&SEGMENT);
    late_payload[27..51].copy_from_slice(&SEGMENT[..24]);
    late_payload[47..51].copy_from_slice(&6_u32.to_le_bytes());
    late_payload[51..].copy_from_slice(&[0xde, 0xad, 0xbe, 0xef, 0xca]);
    let late_error = KcpSegments::parse(&late_payload[..53]).unwrap_err();
    assert_eq!(
        late_error,
        KcpSegmentsParseError::Segment {
            offset: 27,
            error: KcpSegmentParseError::PayloadTruncated {
                required: 30,
                available: 26
            }
        }
    );

    fn require_fused<I: FusedIterator>(_iterator: I) {}
    require_fused(KcpSegmentIter::new(&partial_header));
    let mut iterator = KcpSegmentIter::new(&partial_header);
    assert_eq!(iterator.next().unwrap().unwrap().as_bytes(), SEGMENT);
    assert_eq!(iterator.next(), Some(Err(trailing_error)));
    assert_eq!(iterator.next(), None);
    assert_eq!(iterator.next(), None);
}