ip-v8/rust-ipv8

View on GitHub
rust_ipv8/src/serialization/nestedpayload.rs

Summary

Maintainability
Test Coverage
//! Module containing everything related to Nested payloads
use crate::payloads::Ipv8Payload;
use crate::serialization::varlen::VarLen16;
use crate::serialization::Packet;
use serde;
use serde::de::Deserialize;
use serde::de::Deserializer;
use serde::ser::Serialize;
use serde::ser::SerializeStruct;
use serde::ser::Serializer;

#[derive(PartialEq, Debug)]
/// A struct containing a packet, thus creating a NestedPacket if you will
pub struct NestedPacket(pub Packet);

impl Ipv8Payload for NestedPacket {
    // doesnt have anything but needed for the default implementation (as of right now)
}

impl Serialize for NestedPacket {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let i = VarLen16((self.0).0.to_owned());

        let mut state = serializer.serialize_struct("NestedPacket", self.0.len())?;
        state.serialize_field("payload", &i)?;
        state.end()
    }
}

#[derive(Debug, PartialEq, serde::Deserialize)]
/// this is the actual pattern of a NestedPayload.
/// Used for deserializing. This is again needed because there is no 1:1 mapping between the
/// serialized data and the payload struct. This is the intermediate representation.
struct NestedPayloadPattern(VarLen16);

impl<'de> Deserialize<'de> for NestedPacket {
    /// deserializes an IntroductionRequestPayload
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // first deserialize it to a temporary struct which literally represents the packer
        let payload_temporary: NestedPayloadPattern =
            NestedPayloadPattern::deserialize(deserializer)?;
        Ok(NestedPacket(Packet((payload_temporary.0).0)))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::serialization::Packet;
    use serde;

    #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
    struct TestPayload1 {
        test: NestedPacket,
    }

    impl Ipv8Payload for TestPayload1 {
        // doesnt have anything but needed for the default implementation (as of right now)
    }

    #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
    struct TestPayload2 {
        test: u16,
    }

    impl Ipv8Payload for TestPayload2 {
        // doesnt have anything but needed for the default implementation (as of right now)
    }

    #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
    struct TestPayload3 {}

    impl Ipv8Payload for TestPayload3 {
        // doesnt have anything but needed for the default implementation (as of right now)
    }

    #[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize)]
    struct TestPayload4 {
        test: Vec<u8>,
    }

    impl Ipv8Payload for TestPayload4 {
        // doesnt have anything but needed for the default implementation (as of right now)
    }

    #[test]
    fn integration_test_creation() {
        let mut packet = Packet::new(create_test_header!()).unwrap();
        packet.add(&TestPayload2 { test: 10 }).unwrap();

        let mut packet2 = Packet::new(create_test_header!()).unwrap();
        packet2.add(&TestPayload2 { test: 10 }).unwrap();

        let i = TestPayload1 {
            test: NestedPacket(packet),
        };
        let mut newpacket = Packet::new(create_test_header!()).unwrap();
        newpacket.add(&i).unwrap();

        assert_eq!(
            i,
            newpacket
                .start_deserialize()
                .skip_header()
                .unwrap()
                .next_payload()
                .unwrap()
        );
    }

    #[test]
    fn test_empty() {
        let mut packet = Packet::new(create_test_header!()).unwrap();
        packet.add(&TestPayload3 {}).unwrap();

        let mut packet2 = Packet::new(create_test_header!()).unwrap();
        packet2.add(&TestPayload3 {}).unwrap();

        let i = TestPayload1 {
            test: NestedPacket(packet),
        };

        let mut newpacket = Packet::new(create_test_header!()).unwrap();
        newpacket.add(&i).unwrap();

        assert_eq!(
            i,
            newpacket
                .start_deserialize()
                .skip_header()
                .unwrap()
                .next_payload()
                .unwrap()
        );
    }

    #[test]
    fn test_too_large() {
        let tmp: Vec<u8> = vec![0; (1u32 << 17) as usize];
        let mut packet = Packet::new(create_test_header!()).unwrap();
        packet.add(&TestPayload4 { test: tmp }).unwrap();

        let i = TestPayload1 {
            test: NestedPacket(packet),
        };

        let mut packet = Packet::new(create_test_header!()).unwrap();
        match packet.add(&i) {
            Ok(_) => assert!(false),
            Err(_) => assert!(true),
        }
    }
}