serial_traits 1.1.2

A trait that allows you to serialize to and parse from Vec<u8> buffers. Comes with implementations for primitive types, String and generic collection types (if the item type implements the trait too.)
Documentation
#[cfg(test)]
mod tests {
    use std::collections::{
        BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque,
    };

    use crate::Serializable;
    use rand;
    use rand::Rng;

    #[test]
    fn test_string() {
        let mut rng = rand::rng();
        let mut value = "".to_string();
        for _ in 0..rng.random::<u16>() {
            value.push(rng.random::<char>());
        }

        let mut buffer = value.serialize();
        let result = String::parse(&mut buffer);

        match result {
            Some(outcome) => assert_eq!(value, outcome),
            None => panic!(),
        }
    }

    macro_rules! test_list {
        ($name:ident, $list_type:ty, $adder_name:ident) => {
            #[test]
            fn $name() {
                let mut rng = rand::rng();
                let mut value = <$list_type>::new();
                for _ in 1..rng.random::<u8>() {
                    value.$adder_name(rng.random::<char>());
                }

                let mut buffer = value.serialize();
                let result = <$list_type>::parse(&mut buffer);

                match result {
                    Some(outcome) => assert_eq!(value, outcome),
                    None => panic!(),
                }
            }
        };
    }

    test_list!(test_vec, Vec<char>, push);
    test_list!(test_vecdeque, VecDeque<char>, push_back);
    test_list!(test_linkedlist, LinkedList<char>, push_back);

    macro_rules! test_map {
        ($name:ident, $map_type:ty) => {
            #[test]
            fn $name() {
                let mut rng = rand::rng();
                let mut value = <$map_type>::new();
                for _ in 1..rng.random::<u8>() {
                    value.insert(rng.random::<char>(), rng.random::<char>());
                }

                let mut buffer = value.serialize();
                let result = <$map_type>::parse(&mut buffer);

                match result {
                    Some(outcome) => assert_eq!(value, outcome),
                    None => panic!(),
                }
            }
        };
    }

    test_map!(test_map_hash, HashMap<char, char>);
    test_map!(test_map_btree, BTreeMap<char, char>);

    macro_rules! test_set {
        ($name:ident, $set_type:ty) => {
            #[test]
            fn $name() {
                let mut rng = rand::rng();
                let mut value = <$set_type>::new();
                for _ in 1..rng.random::<u8>() {
                    value.insert(rng.random::<char>());
                }

                let mut buffer = value.serialize();
                let result = <$set_type>::parse(&mut buffer);

                match result {
                    Some(outcome) => {
                        if value.len() != outcome.len() {
                            panic!("set length didn't equal");
                        }

                        for element in value {
                            if !outcome.contains(&element) {
                                panic!("set didn't contain item");
                            }
                        }
                    }
                    None => panic!(),
                }
            }
        };
    }

    test_set!(test_set_hash, HashSet<char>);
    test_set!(test_set_btree, BTreeSet<char>);

    #[test]
    fn test_binaryheap() {
        let mut rng = rand::rng();
        let mut value = <BinaryHeap<char>>::new();
        for _ in 1..rng.random::<u8>() {
            value.push(rng.random::<char>());
        }

        let mut buffer = value.serialize();
        let result = <BinaryHeap<char>>::parse(&mut buffer);

        match result {
            Some(outcome) => {
                if value.len() != outcome.len() {
                    panic!("heap size didn't equal");
                }

                for element in value {
                    let mut contains = false;
                    for other in &outcome {
                        if element == *other {
                            contains = true;
                        }
                    }
                    if !contains {
                        panic!("heap didn't contain item");
                    }
                }
            }
            None => panic!(),
        }
    }
}