network/fundamentals/ip/
ipv6.rs1use core::fmt::Display;
2
3#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
4#[repr(transparent)]
5pub struct Ipv6([u8; 16]); impl Ipv6 {
8 pub const fn new(value: [u16; 8]) -> Self {
9 let mut bytes = [0; 16];
10 let mut i = 0;
11 while i < 8 {
12 let segment = value[i].to_be_bytes();
13 bytes[i * 2] = segment[0];
14 bytes[i * 2 + 1] = segment[1];
15 i += 1;
16 }
17 Self(bytes)
18 }
19
20 pub const fn into_inner(self) -> [u8; 16] {
21 self.0
22 }
23
24 pub const fn from_inner(value: [u8; 16]) -> Self {
25 Self(value)
26 }
27
28 pub const fn into_smoltcp(self) -> core::net::Ipv6Addr {
29 core::net::Ipv6Addr::from_octets(self.0)
30 }
31
32 pub const fn from_smoltcp(value: &core::net::Ipv6Addr) -> Self {
33 Self(value.octets())
34 }
35}
36
37impl TryFrom<&str> for Ipv6 {
38 type Error = ();
39
40 fn try_from(value: &str) -> Result<Self, Self::Error> {
41 let mut result = [0; 8];
42 let mut index = 0;
43
44 for part in value.split(':') {
45 if index >= 8 {
46 return Err(());
47 }
48 let part = u16::from_str_radix(part, 16).map_err(|_| ())?;
49 result[index] = part;
50 index += 1;
51 }
52
53 if index != 8 {
54 return Err(());
55 }
56
57 Ok(Self::new(result))
58 }
59}
60
61impl Display for Ipv6 {
62 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
63 write!(
64 f,
65 "{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}:{:x}{:x}",
66 self.0[0],
67 self.0[1],
68 self.0[2],
69 self.0[3],
70 self.0[4],
71 self.0[5],
72 self.0[6],
73 self.0[7],
74 self.0[8],
75 self.0[9],
76 self.0[10],
77 self.0[11],
78 self.0[12],
79 self.0[13],
80 self.0[14],
81 self.0[15]
82 )
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use alloc::string::ToString;
89
90 use super::*;
91
92 #[test]
93 fn test_ipv6_display() {
94 let ip = Ipv6::new([0; 8]);
95
96 assert_eq!(ip.to_string(), "00:00:00:00:00:00:00:00");
97 }
98
99 #[test]
100 fn test_ipv6_try_from() {
101 let ip = Ipv6::try_from("0:0:0:0:0:0:0:0").unwrap();
102
103 assert_eq!(ip.0, [0; 16]);
104
105 Ipv6::try_from("0:0:0:0:0:0:0:0:0").unwrap_err();
106
107 Ipv6::try_from("0:0:0:0:0:0:0").unwrap_err();
108
109 let ip = Ipv6::try_from("1234:5678:9abc:def0:1234:5678:9abc:def0").unwrap();
110
111 assert_eq!(
112 ip.0,
113 [
114 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc,
115 0xde, 0xf0
116 ]
117 );
118 }
119}