1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use anyhow::Result;
use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};

pub trait Bytes {
  fn to_bytes(&self) -> Box<[u8]>;
  fn from_bytes(buf: &[u8]) -> Result<Self>
  where
    Self: Sized;
}

impl Bytes for bool {
  fn to_bytes(&self) -> Box<[u8]> {
    ([if *self { '1' } else { '0' } as u8]).into()
  }

  fn from_bytes(buf: &[u8]) -> Result<Self> {
    for i in buf {
      if *i == b'0' {
        return Ok(false);
      }
      return Ok(true);
    }
    Ok(true)
  }
}

impl Bytes for u16 {
  fn to_bytes(&self) -> Box<[u8]> {
    self.to_le_bytes().into()
  }

  fn from_bytes(buf: &[u8]) -> Result<Self> {
    Ok(u16::from_le_bytes(buf[..2].try_into()?))
  }
}

impl Bytes for SocketAddrV4 {
  fn to_bytes(&self) -> Box<[u8]> {
    let o = self.ip().octets();
    let p = self.port().to_le_bytes();
    [o[0], o[1], o[2], o[3], p[0], p[1]].into()
  }
  fn from_bytes(buf: &[u8]) -> Result<Self> {
    let li: [u8; 6] = buf.try_into()?;

    Ok(Self::new(
      [li[0], li[1], li[2], li[3]].into(),
      u16::from_le_bytes([li[4], li[5]]),
    ))
  }
}

impl Bytes for SocketAddrV6 {
  fn to_bytes(&self) -> Box<[u8]> {
    let o = self.ip().octets();
    let p = self.port().to_le_bytes();
    [
      o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9], o[10], o[11], o[12], o[13],
      o[14], o[15], p[0], p[1],
    ]
    .into()
  }
  fn from_bytes(buf: &[u8]) -> Result<Self> {
    let o: [u8; 18] = buf.try_into()?;
    Ok(Self::new(
      [
        o[0], o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9], o[10], o[11], o[12], o[13],
        o[14], o[15],
      ]
      .into(),
      u16::from_le_bytes([o[16], o[17]]),
      0,
      0,
    ))
  }
}

impl Bytes for SocketAddr {
  fn to_bytes(&self) -> Box<[u8]> {
    match self {
      SocketAddr::V4(addr) => addr.to_bytes(),
      SocketAddr::V6(addr) => addr.to_bytes(),
    }
  }
  fn from_bytes(buf: &[u8]) -> Result<Self> {
    Ok(if buf.len() == 18 {
      SocketAddr::V6(SocketAddrV6::from_bytes(buf)?)
    } else {
      SocketAddr::V4(SocketAddrV4::from_bytes(buf)?)
    })
  }
}