1use std::{
2 io::{Read, Write},
3 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
4};
5
6use super::{DataFormat, DataFormatReader, DataReadError, DataWriteError};
7
8impl DataFormat for Ipv4Addr {
9 type Header = ();
10 const LATEST_HEADER: Self::Header = ();
11
12 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
13 Ok(writer.write(&self.octets())?)
14 }
15
16 fn read_data<R: Read>(reader: &mut R, _header: &Self::Header) -> Result<Self, DataReadError> {
17 let mut octets = [0u8; 4];
18 reader.read_exact(&mut octets)?;
19 Ok(Ipv4Addr::from(octets))
20 }
21}
22
23impl DataFormat for Ipv6Addr {
24 type Header = ();
25 const LATEST_HEADER: Self::Header = ();
26
27 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
28 Ok(writer.write(&self.octets())?)
29 }
30
31 fn read_data<R: Read>(reader: &mut R, _header: &Self::Header) -> Result<Self, DataReadError> {
32 let mut octets = [0u8; 16];
33 reader.read_exact(&mut octets)?;
34 Ok(Ipv6Addr::from(octets))
35 }
36}
37
38impl DataFormat for IpAddr {
39 type Header = ();
40 const LATEST_HEADER: Self::Header = ();
41
42 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
43 match self {
44 IpAddr::V4(addr) => Ok(0u8.write_data(writer)? + addr.write_data(writer)?),
45 IpAddr::V6(addr) => Ok(1u8.write_data(writer)? + addr.write_data(writer)?),
46 }
47 }
48
49 fn read_data<R: Read>(reader: &mut R, _header: &Self::Header) -> Result<Self, DataReadError> {
50 match reader.read_data(&())? {
51 0u8 => Ok(IpAddr::V4(reader.read_data(&())?)),
52 1u8 => Ok(IpAddr::V6(reader.read_data(&())?)),
53 n => Err(DataReadError::Custom(format!(
54 "invalid IpAddr discriminant: {n}"
55 ))),
56 }
57 }
58}
59
60impl DataFormat for SocketAddrV4 {
61 type Header = ();
62 const LATEST_HEADER: Self::Header = ();
63
64 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
65 Ok(self.ip().write_data(writer)? + self.port().write_data(writer)?)
66 }
67
68 fn read_data<R: Read>(reader: &mut R, header: &Self::Header) -> Result<Self, DataReadError> {
69 Ok(SocketAddrV4::new(
70 reader.read_data(header)?,
71 reader.read_data(header)?,
72 ))
73 }
74}
75
76impl DataFormat for SocketAddrV6 {
77 type Header = ();
78 const LATEST_HEADER: Self::Header = ();
79
80 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
81 Ok(self.ip().write_data(writer)? + self.port().write_data(writer)?)
82 }
83
84 fn read_data<R: Read>(reader: &mut R, header: &Self::Header) -> Result<Self, DataReadError> {
85 Ok(SocketAddrV6::new(
86 reader.read_data(header)?,
87 reader.read_data(header)?,
88 0,
89 0,
90 ))
91 }
92}
93
94impl DataFormat for SocketAddr {
95 type Header = ();
96 const LATEST_HEADER: Self::Header = ();
97
98 fn write_data<W: Write>(&self, writer: &mut W) -> Result<usize, DataWriteError> {
99 match self {
100 SocketAddr::V4(addr) => Ok(0u8.write_data(writer)? + addr.write_data(writer)?),
101 SocketAddr::V6(addr) => Ok(1u8.write_data(writer)? + addr.write_data(writer)?),
102 }
103 }
104
105 fn read_data<R: Read>(reader: &mut R, _header: &Self::Header) -> Result<Self, DataReadError> {
106 match reader.read_data(&())? {
107 0u8 => Ok(SocketAddr::V4(reader.read_data(&())?)),
108 1u8 => Ok(SocketAddr::V6(reader.read_data(&())?)),
109 n => Err(DataReadError::Custom(format!(
110 "invalid SocketAddr discriminant: {n}"
111 ))),
112 }
113 }
114}
115
116#[cfg(test)]
117#[rustfmt::skip]
118mod test {
119 use crate::format::DataFormat;
120 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
121
122 macro_rules! case {
123 ($name:ident, $ty:ty, $a:expr, $b:expr) => {
124 #[test]
125 fn $name() {
126 let mut data = Vec::new();
127 $a.write_data(&mut data).unwrap();
128 assert_eq!(data, &$b);
129
130 let mut reader = &data[..];
131 let read_value = <$ty>::read_data(&mut reader, &()).unwrap();
132 assert_eq!(read_value, $a);
133
134 }
135
136 };
137 }
138
139 case!(ip_localhost, Ipv4Addr, Ipv4Addr::LOCALHOST, [127, 0, 0, 1]);
140 case!(ip_v6_localhost, Ipv6Addr, "::1".parse::<Ipv6Addr>().unwrap(), [
141 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 1,
143 ]);
144 case!(ip_v4, IpAddr, IpAddr::V4(Ipv4Addr::LOCALHOST), [0, 127, 0, 0, 1]);
145 case!(ip_v6, IpAddr, IpAddr::V6("::1".parse::<Ipv6Addr>().unwrap()), [
146 1,
147 0, 0, 0, 0, 0, 0, 0, 0,
148 0, 0, 0, 0, 0, 0, 0, 1,
149 ]);
150
151 case!(socket_v4, SocketAddrV4, SocketAddrV4::new(Ipv4Addr::LOCALHOST, 80), [
152 127, 0, 0, 1,
153 80, 0,
154 ]);
155 case!(socket_v6, SocketAddrV6, SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0), [
156 0, 0, 0, 0, 0, 0, 0, 0,
157 0, 0, 0, 0, 0, 0, 0, 1,
158 144, 31,
159 ]);
160
161 case!(socket_v4_socket, SocketAddr, SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080)), [
162 0,
163 127, 0, 0, 1,
164 144, 31,
165 ]);
166
167 case!(socket_v6_socket, SocketAddr, SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 8080, 0, 0)), [
168 1,
169 0, 0, 0, 0, 0, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 1,
171 144, 31,
172 ]);
173}