1use alloc::boxed::Box;
2use anyhow::Result;
3use core::{fmt, pin::Pin};
4use futures::{AsyncRead, AsyncWrite};
5
6pub trait Socket: AsyncRead + AsyncWrite + 'static {
7 fn connect(address: SocketAddr) -> Result<Pin<Box<dyn Socket + Send>>>
8 where
9 Self: Sized;
10}
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct Ipv4Addr(pub [u16; 4]);
15
16impl Ipv4Addr {
17 pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Self {
18 Self([a as u16, b as u16, c as u16, d as u16])
19 }
20
21 pub const fn octets(&self) -> [u8; 4] {
22 [
23 self.0[0] as u8,
24 self.0[1] as u8,
25 self.0[2] as u8,
26 self.0[3] as u8,
27 ]
28 }
29
30 pub fn from_bytes(bytes: [u8; 4]) -> Self {
31 Self([
32 bytes[0] as u16,
33 bytes[1] as u16,
34 bytes[2] as u16,
35 bytes[3] as u16,
36 ])
37 }
38}
39
40impl fmt::Display for Ipv4Addr {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 let octets = self.octets();
43 write!(f, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
44 }
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
49pub struct Ipv6Addr(pub [u16; 8]);
50
51impl Ipv6Addr {
52 pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Self {
53 Self([a, b, c, d, e, f, g, h])
54 }
55
56 pub const fn segments(&self) -> [u16; 8] {
57 self.0
58 }
59
60 pub fn octets(&self) -> [u8; 16] {
61 let mut octets = [0u8; 16];
62 for (i, &segment) in self.0.iter().enumerate() {
63 octets[i * 2] = (segment >> 8) as u8;
64 octets[i * 2 + 1] = (segment & 0xff) as u8;
65 }
66 octets
67 }
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
72pub enum IpAddr {
73 V4(Ipv4Addr),
74 V6(Ipv6Addr),
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
79pub struct SocketAddr {
80 ip: IpAddr,
81 port: u16,
82}
83
84impl SocketAddr {
85 pub const fn new(ip: IpAddr, port: u16) -> Self {
86 Self { ip, port }
87 }
88
89 pub const fn v4(ip: Ipv4Addr, port: u16) -> Self {
90 Self {
91 ip: IpAddr::V4(ip),
92 port,
93 }
94 }
95
96 pub const fn v6(ip: Ipv6Addr, port: u16) -> Self {
97 Self {
98 ip: IpAddr::V6(ip),
99 port,
100 }
101 }
102
103 pub const fn ip(&self) -> IpAddr {
104 self.ip
105 }
106
107 pub const fn port(&self) -> u16 {
108 self.port
109 }
110}