allium 0.1.3

Allium is a Rust library for onion routing.
Documentation
use bytes::{Buf, BufMut, BytesMut};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

pub trait FromBytes {
    fn read_from(buf: &mut BytesMut) -> Self
    where
        Self: Sized;
}

pub trait TryFromBytes<E> {
    fn try_read_from(buf: &mut BytesMut) -> std::result::Result<Self, E>
    where
        Self: Sized;
}

impl<T, E> TryFromBytes<E> for T
where
    std::result::Result<T, E>: FromBytes,
{
    fn try_read_from(buf: &mut BytesMut) -> std::result::Result<Self, E>
    where
        Self: Sized,
    {
        std::result::Result::<T, E>::read_from(buf)
    }
}

pub trait ToBytes {
    fn size(&self) -> usize;
    fn write_to(&self, buf: &mut BytesMut);
}

impl FromBytes for Ipv4Addr {
    fn read_from(buf: &mut BytesMut) -> Self {
        let mut octets = [0u8; 4];
        buf.copy_to_slice(&mut octets);
        Ipv4Addr::from(octets)
    }
}

impl FromBytes for Ipv6Addr {
    fn read_from(buf: &mut BytesMut) -> Self {
        let mut octets = [0u8; 16];
        buf.copy_to_slice(&mut octets);
        Ipv6Addr::from(octets)
    }
}

pub fn get_ip_addr(buf: &mut BytesMut, is_ipv6: bool) -> IpAddr {
    if !is_ipv6 {
        IpAddr::V4(Ipv4Addr::read_from(buf))
    } else {
        IpAddr::V6(Ipv6Addr::read_from(buf))
    }
}

impl ToBytes for IpAddr {
    fn size(&self) -> usize {
        match self {
            IpAddr::V4(_) => 4,
            IpAddr::V6(_) => 16,
        }
    }

    fn write_to(&self, buf: &mut BytesMut) {
        match self {
            IpAddr::V4(ip) => buf.put(ip.octets().as_ref()),
            IpAddr::V6(ip) => buf.put(ip.octets().as_ref()),
        }
    }
}