feeless 0.1.11

A Nano (cryptocurrency) node and utilities such as nano addresses, hashing blocks, signing, etc.
Documentation
use crate::expect_len;
use crate::node::header::Header;
use crate::node::wire::Wire;
use std::net::{Ipv6Addr, SocketAddrV6};
use std::str::FromStr;

pub struct Peer(SocketAddrV6);

impl Peer {
    pub const LEN: usize = 18;
    pub const ADDR_LEN: usize = 16;

    pub fn socket_addr_v6(&self) -> SocketAddrV6 {
        self.0
    }
}

impl FromStr for Peer {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(Peer(SocketAddrV6::from_str(s)?))
    }
}

impl Wire for Peer {
    fn serialize(&self) -> Vec<u8> {
        let mut v = Vec::with_capacity(Self::LEN);
        v.extend_from_slice(&self.0.ip().octets());
        v.push(self.0.port() as u8);
        v.push((self.0.port() >> 8) as u8);
        v
    }

    fn deserialize(_: Option<&Header>, data: &[u8]) -> anyhow::Result<Self>
    where
        Self: Sized,
    {
        expect_len(data.len(), Self::len(None)?, "Peer")?;

        let mut addr: [u8; Self::ADDR_LEN] = [0u8; Self::ADDR_LEN];
        addr.copy_from_slice(&data[0..Self::ADDR_LEN]);
        let port: u16 = data[Self::ADDR_LEN] as u16 + data[Self::ADDR_LEN + 1] as u16 * 256;

        Ok(Self(SocketAddrV6::new(Ipv6Addr::from(addr), port, 0, 0)))
    }

    fn len(_header: Option<&Header>) -> anyhow::Result<usize> {
        Ok(Peer::LEN)
    }
}

impl std::fmt::Debug for Peer {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Peer({})", self.0)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn serialize() {
        let addr = "[::ffff:255.254.253.252]:7075";
        let peer = Peer::from_str(addr).unwrap();
        let v = peer.serialize();
        let peer2 = Peer::deserialize(None, v.as_slice()).unwrap();
        let addr2 = peer2.socket_addr_v6().to_string();
        assert_eq!(addr, addr2);
    }
}