copernica_packets/
reply_to.rs

1use {
2    copernica_common::{u8_to_u16, u16_to_u8, constants::*},
3    std::{fmt, net::{SocketAddrV4, SocketAddrV6}},
4    anyhow::{Result, anyhow},
5    bincode,
6};
7pub type Hertz = u32;
8#[derive(Clone, Eq, Hash, PartialEq)]
9pub enum ReplyTo {
10    Mpsc,
11    UdpIpV4(SocketAddrV4),
12    UdpIpV6(SocketAddrV6),
13    Rf(Hertz),
14}
15impl ReplyTo {
16    pub fn from_bytes(data: &[u8]) -> Result<Self> {
17        let mut reply_to_index = [0u8; 2];
18        reply_to_index.clone_from_slice(&[data[REPLY_TO_INDEX_START], data[REPLY_TO_INDEX_END]]);
19        let reply_to_index: u16 = u8_to_u16(reply_to_index);
20        let rt = match reply_to_index {
21            REPLY_TO_MPSC_INDEX => {
22                ReplyTo::Mpsc
23            },
24            REPLY_TO_RF_INDEX => {
25                let address = &data[REPLY_TO_START..REPLY_TO_MPSC_SIZE];
26                let address = bincode::deserialize(address)?;
27                ReplyTo::Rf(address)
28            },
29            REPLY_TO_UDPIPV4_INDEX => {
30                let address = &data[REPLY_TO_START..REPLY_TO_UDPIPV4_SIZE];
31                let address = bincode::deserialize(address)?;
32                ReplyTo::UdpIpV4(address)
33            },
34            REPLY_TO_UDPIPV6_INDEX => {
35                let address = &data[REPLY_TO_START..REPLY_TO_UDPIPV6_SIZE];
36                let address = bincode::deserialize(address)?;
37                ReplyTo::UdpIpV6(address)
38            },
39            i => return Err(anyhow!("Deserializing ReplyTo hit an unrecognised type or variation: {}", i))
40        };
41        Ok(rt)
42    }
43    pub fn as_bytes(&self) -> Result<Vec<u8>> {
44        let mut buf: Vec<u8> = vec![];
45        let padding: &[u8; REPLY_TO_SIZE] = &[0u8; REPLY_TO_SIZE];
46        match self {
47            ReplyTo::Mpsc => {
48                buf.extend_from_slice(&u16_to_u8(REPLY_TO_MPSC_INDEX));
49                buf.extend_from_slice(&padding[..]);
50            },
51            ReplyTo::Rf(hz) => {
52                buf.extend_from_slice(&u16_to_u8(REPLY_TO_RF_INDEX));
53                let address = bincode::serialize(&hz)?;
54                buf.extend_from_slice(&address[..]);
55                buf.extend_from_slice(&padding[address.len()..]);
56            }
57            ReplyTo::UdpIpV4(addr) => {
58                buf.extend_from_slice(&u16_to_u8(REPLY_TO_UDPIPV4_INDEX));
59                let address = bincode::serialize(&addr)?;
60                buf.extend_from_slice(&address[..]);
61                buf.extend_from_slice(&padding[address.len()..]);
62            }
63            ReplyTo::UdpIpV6(addr) => {
64                buf.extend_from_slice(&u16_to_u8(REPLY_TO_UDPIPV6_INDEX));
65                let address = bincode::serialize(&addr)?;
66                buf.extend_from_slice(&address[..]);
67                buf.extend_from_slice(&padding[address.len()..]);
68            }
69        }
70        Ok(buf)
71    }
72}
73impl fmt::Debug for ReplyTo {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        match self {
76            ReplyTo::UdpIpV4(addr) => {
77                write!(f, "ReplyTo::UdpIpV4({})", addr)
78            },
79            ReplyTo::UdpIpV6(addr) => {
80                write!(f, "ReplyTo::UdpIpV6({})", addr)
81            },
82            ReplyTo::Mpsc => {
83                write!(f, "ReplyTo::Mpsc")
84            },
85            ReplyTo::Rf(hertz) => {
86                write!(f, "ReplyTo::Rf({})", hertz)
87            },
88        }
89    }
90}