nettext 0.4.1

A text-based data format for cryptographic network protocols
Documentation
//! Serde serialization and deserialization for nettext

mod de;
mod error;
mod ser;

pub use de::{from_bytes, from_term, Deserializer};
pub use error::{Error, Result};
pub use ser::{to_bytes, to_term, Serializer};

#[cfg(test)]
mod tests {
    use super::*;
    use crate::debug;
    use serde::{Deserialize, Serialize};
    use std::collections::HashMap;

    fn test_bidir<T: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug>(
        input: T,
        expected_concise: &str,
    ) {
        eprintln!("Expecting: {}", expected_concise);

        let ser = to_bytes(&input).unwrap();
        let ser = debug(&ser);
        eprintln!("Serialized: {}", ser);
        assert_eq!(from_bytes::<T>(ser.as_bytes()).unwrap(), input);

        let ser_concise = to_term(&input).unwrap().encode_concise();
        let ser_concise = debug(&ser_concise);
        eprintln!("Serialized (concise): {}", ser_concise);
        assert_eq!(ser_concise, expected_concise);
        assert_eq!(from_bytes::<T>(ser_concise.as_bytes()).unwrap(), input);
    }

    #[test]
    fn test_struct() {
        #[derive(Serialize, Deserialize, PartialEq, Debug)]
        struct Test {
            int: u32,
            seq: Vec<String>,
        }

        let input = Test {
            int: 1,
            seq: vec!["a".to_string(), "b".to_string()],
        };
        let expected = r#"Test {int=1;seq=[YQ;Yg]}"#;
        test_bidir(input, expected);

        let input = vec![
            Test {
                int: 1,
                seq: vec!["a".to_string(), "b".to_string()],
            },
            Test {
                int: 2,
                seq: vec!["c".to_string(), "d".to_string()],
            },
        ];
        let expected = r#"[Test {int=1;seq=[YQ;Yg]};Test {int=2;seq=[Yw;ZA]}]"#;
        test_bidir(input, expected);
    }

    #[test]
    fn test_enum() {
        #[derive(Serialize, Deserialize, PartialEq, Debug)]
        enum E {
            Unit,
            Newtype(u32),
            Tuple(u32, u32),
            Struct { a: u32 },
        }

        let input = E::Unit;
        let expected = r#"E.Unit"#;
        test_bidir(input, expected);

        let input = E::Newtype(1);
        let expected = r#"E.Newtype 1"#;
        test_bidir(input, expected);

        let input = E::Tuple(1, 2);
        let expected = r#"E.Tuple 1 2"#;
        test_bidir(input, expected);

        let input = E::Struct { a: 1 };
        let expected = r#"E.Struct {a=1}"#;
        test_bidir(input, expected);

        let input = vec![
            E::Unit,
            E::Unit,
            E::Newtype(1),
            E::Tuple(1, 2),
            E::Struct { a: 1 },
            E::Tuple(3, 2),
        ];
        let expected = r#"[E.Unit;E.Unit;E.Newtype 1;E.Tuple 1 2;E.Struct {a=1};E.Tuple 3 2]"#;
        test_bidir(input, expected);
    }

    #[test]
    fn test_seq1() {
        let input = (1, 2, 3, 4);
        let expected = r#"1 2 3 4"#;
        test_bidir(input, expected);
    }

    #[test]
    fn test_list() {
        let input = vec![1, 2, 3, 4];
        let expected = r#"[1;2;3;4]"#;
        test_bidir(input, expected);
    }

    #[test]
    fn test_seqlist() {
        let input = vec![(1, 2), (2, 3), (3, 4), (5, 6)];
        let expected = r#"[1 2;2 3;3 4;5 6]"#;
        test_bidir(input, expected);
    }

    #[test]
    fn test_dict() {
        let mut input = HashMap::new();
        input.insert("hello".to_string(), "world".to_string());
        input.insert("dont".to_string(), "panic".to_string());
        let expected = r#"{ZG9udA=cGFuaWM;aGVsbG8=d29ybGQ}"#;
        test_bidir(input, expected);

        let mut input = HashMap::new();
        input.insert(12, vec![42, 125]);
        input.insert(33, vec![19, 22, 21]);
        let expected = r#"{12=[42;125];33=[19;22;21]}"#;
        test_bidir(input, expected);
    }
}