netgauze-parse-utils 0.13.0

Serialization/Deserialization utilities for NetGauze
Documentation
// Copyright (C) 2022-present The NetGauze Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Various functions used in testing the correctness or
//! serializing/deserializing wire protocols

use crate::reader::SliceReader;
use crate::traits::{
    ParseFrom, ParseFromWithOneInput, ParseFromWithThreeInputs, ParseFromWithTwoInputs,
};
use crate::{WritablePdu, WritablePduWithOneInput, WritablePduWithTwoInputs};
use std::fmt::Debug;
use std::io::Cursor;

/// Helper method to combine multiple vectors into one
pub fn combine(v: Vec<&[u8]>) -> Vec<u8> {
    v.iter()
        .flat_map(|x| x.iter())
        .cloned()
        .collect::<Vec<u8>>()
}

/// Fancier assert to for more meaningful error messages
pub fn test_parsed_completely_bytes_reader<'a, T, E>(input: &'a [u8], expected: &T) -> T
where
    T: ParseFrom<'a, Error = E> + PartialEq + Debug,
    E: Debug,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(&mut bytes_reader);
    assert!(
        parsed.is_ok(),
        "Message failed parsing, while expecting it to pass.\n\tExpected : {expected:?}\n\tParsed msg: {parsed:?}"
    );
    let value = parsed.unwrap();
    assert_eq!(&value, expected);
    assert_eq!(
        bytes_reader.remaining(),
        0,
        "Not all the input is consumed by the parser, didn't consume: {:?}",
        bytes_reader
            .read_bytes(bytes_reader.remaining())
            .unwrap()
            .to_vec(),
    );
    value
}

pub fn test_parsed_completely_with_one_input_bytes_reader<'a, I, T, E>(
    input: &'a [u8],
    parser_input: I,
    expected: &T,
) -> T
where
    T: ParseFromWithOneInput<'a, I, Error = E> + PartialEq + Debug,
    E: Debug,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(&mut bytes_reader, parser_input);
    assert!(
        parsed.is_ok(),
        "Message failed parsing, while expecting it to pass.\n\tExpected : {expected:?}\n\tParsed msg: {parsed:?}"
    );
    let value = parsed.unwrap();
    assert_eq!(&value, expected);
    assert_eq!(
        bytes_reader.remaining(),
        0,
        "Not all the input is consumed by the parser, didn't consume: {:?}",
        bytes_reader
            .read_bytes(bytes_reader.remaining())
            .unwrap()
            .to_vec(),
    );
    value
}

pub fn test_parsed_completely_with_two_inputs_bytes_reader<'a, T, I, K, E>(
    input: &'a [u8],
    parser_input1: I,
    parser_input2: K,
    expected: &T,
) -> T
where
    T: ParseFromWithTwoInputs<'a, I, K, Error = E> + PartialEq + Debug,
    E: Debug,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(&mut bytes_reader, parser_input1, parser_input2);
    assert!(
        parsed.is_ok(),
        "Message failed parsing, while expecting it to pass.\n\tExpected : {expected:?}\n\tParsed msg: {parsed:?}"
    );
    let value = parsed.unwrap();
    assert_eq!(&value, expected);
    assert_eq!(
        bytes_reader.remaining(),
        0,
        "Not all the input is consumed by the parser, didn't consume: {:?}",
        bytes_reader
            .read_bytes(bytes_reader.remaining())
            .unwrap()
            .to_vec(),
    );
    value
}

pub fn test_parsed_completely_with_three_inputs_bytes_reader<'a, T, I1, I2, I3, E>(
    input: &'a [u8],
    parser_input1: I1,
    parser_input2: I2,
    parser_input3: I3,
    expected: &T,
) -> T
where
    T: ParseFromWithThreeInputs<'a, I1, I2, I3, Error = E> + PartialEq + Debug,
    E: Debug,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(
        &mut bytes_reader,
        parser_input1,
        parser_input2,
        parser_input3,
    );
    assert!(
        parsed.is_ok(),
        "Message failed parsing, while expecting it to pass.\n\tExpected : {expected:?}\n\tParsed msg: {parsed:?}"
    );
    let value = parsed.unwrap();
    assert_eq!(&value, expected);
    assert_eq!(
        bytes_reader.remaining(),
        0,
        "Not all the input is consumed by the parser, didn't consume: {:?}",
        bytes_reader
            .read_bytes(bytes_reader.remaining())
            .unwrap()
            .to_vec(),
    );
    value
}

pub fn test_parse_error_bytes_reader<'a, T, E>(input: &'a [u8], expected_err: &E)
where
    T: ParseFrom<'a, Error = E> + PartialEq + Debug,
    E: Debug + PartialEq,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(&mut bytes_reader);
    assert!(
        parsed.is_err(),
        "Message was parsed, while expecting it to fail.\n\tExpected : {expected_err:?}\n\tParsed msg: {parsed:?}"
    );

    let parsed_error = parsed.unwrap_err();
    assert_eq!(&parsed_error, expected_err);
}

/// Fancier assert to for more meaningful error messages
pub fn test_parse_error_with_one_input_bytes_reader<'a, T, I, E>(
    input: &'a [u8],
    parser_input: I,
    expected_err: &'a E,
) where
    T: ParseFromWithOneInput<'a, I, Error = E> + PartialEq + Debug,
    E: Debug + PartialEq,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(&mut bytes_reader, parser_input);
    assert!(
        parsed.is_err(),
        "Message was parsed, while expecting it to fail.\n\tExpected : {expected_err:?}\n\tParsed msg: {parsed:?}"
    );

    let parsed_error = parsed.unwrap_err();
    assert_eq!(&parsed_error, expected_err);
}

pub fn test_parse_error_with_two_inputs_bytes_reader<'a, T, I, K, E>(
    input: &'a [u8],
    parser_input1: I,
    parser_input2: K,
    expected_err: &E,
) where
    T: ParseFromWithTwoInputs<'a, I, K, Error = E> + PartialEq + Debug,
    E: Debug + PartialEq,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(&mut bytes_reader, parser_input1, parser_input2);
    assert!(
        parsed.is_err(),
        "Message was parsed, while expecting it to fail.\n\tExpected : {expected_err:?}\n\tParsed msg: {parsed:?}"
    );

    let parsed_error = parsed.unwrap_err();
    assert_eq!(&parsed_error, expected_err);
}

pub fn test_parse_error_with_three_inputs_bytes_reader<'a, T, I1, I2, I3, E>(
    input: &'a [u8],
    parser_input1: I1,
    parser_input2: I2,
    parser_input3: I3,
    expected_err: &E,
) where
    T: ParseFromWithThreeInputs<'a, I1, I2, I3, Error = E> + PartialEq + Debug,
    E: Debug + PartialEq,
{
    let mut bytes_reader = SliceReader::new(input);
    let parsed = T::parse(
        &mut bytes_reader,
        parser_input1,
        parser_input2,
        parser_input3,
    );
    assert!(
        parsed.is_err(),
        "Message was parsed, while expecting it to fail.\n\tExpected : {expected_err:?}\n\tParsed msg: {parsed:?}"
    );

    let parsed_error = parsed.unwrap_err();
    assert_eq!(&parsed_error, expected_err);
}

pub fn test_write<T: WritablePdu<E>, E: Eq>(input: &T, expected: &[u8]) -> Result<(), E> {
    let mut buf: Vec<u8> = vec![];
    let mut cursor = Cursor::new(&mut buf);
    input.write(&mut cursor)?;
    assert_eq!(
        buf, expected,
        "Serialized buffer is different the the expected one"
    );
    assert_eq!(
        input.len(),
        expected.len(),
        "Packet::len() is different the serialized buffer length"
    );
    Ok(())
}

pub fn test_write_with_one_input<I: Clone, T: WritablePduWithOneInput<I, E>, E: Eq>(
    input: &T,
    parser_input: I,
    expected: &[u8],
) -> Result<(), E> {
    let mut buf: Vec<u8> = vec![];
    let mut cursor = Cursor::new(&mut buf);
    input.write(&mut cursor, parser_input.clone())?;
    assert_eq!(
        buf, expected,
        "Serialized buffer is different the the expected one"
    );
    assert_eq!(
        input.len(parser_input),
        expected.len(),
        "Packet::len() is different the serialized buffer length"
    );
    Ok(())
}

pub fn test_write_with_two_inputs<
    I1: Clone,
    I2: Clone,
    T: WritablePduWithTwoInputs<I1, I2, E>,
    E: Eq,
>(
    input: &T,
    parser_input1: I1,
    parser_input2: I2,
    expected: &[u8],
) -> Result<(), E> {
    let mut buf: Vec<u8> = vec![];
    let mut cursor = Cursor::new(&mut buf);
    input.write(&mut cursor, parser_input1.clone(), parser_input2.clone())?;
    assert_eq!(
        buf, expected,
        "Serialized buffer is different the the expected one"
    );
    assert_eq!(
        input.len(parser_input1, parser_input2),
        expected.len(),
        "Packet::len() is different the serialized buffer length"
    );
    Ok(())
}