1#![no_std]
2
3use core::{
4 fmt::{Debug, Display},
5 ops::{Deref, DerefMut, Index, IndexMut},
6};
7
8use scroll::{
9 ctx::{SizeWith, TryFromCtx, TryIntoCtx},
10 Pread, Pwrite,
11};
12
13pub const BROADCAST: MACAddress = MACAddress::new([0xff; 6]);
15pub const ZERO: MACAddress = MACAddress::new([0x00; 6]);
17
18#[repr(transparent)]
19#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
20pub struct MACAddress(pub [u8; 6]);
22impl MACAddress {
23 pub const fn is_multicast(&self) -> bool {
25 self.0[0] & 0x1 != 0x0
26 }
27 pub const fn is_local(&self) -> bool {
29 self.0[0] & 0x2 != 0x0
30 }
31 pub const fn new(address: [u8; 6]) -> Self {
32 Self(address)
33 }
34}
35impl From<[u8; 6]> for MACAddress {
36 fn from(value: [u8; 6]) -> Self {
37 Self(value)
38 }
39}
40impl From<MACAddress> for [u8; 6] {
41 fn from(value: MACAddress) -> Self {
42 *value.deref()
43 }
44}
45impl SizeWith for MACAddress {
46 fn size_with(_ctx: &()) -> usize {
47 6
48 }
49}
50impl TryFromCtx<'_> for MACAddress {
51 type Error = scroll::Error;
52 #[inline]
53 fn try_from_ctx(from: &'_ [u8], _ctx: ()) -> Result<(Self, usize), Self::Error> {
54 Ok((MACAddress::new(from.pread(0)?), 6))
55 }
56}
57impl TryIntoCtx for MACAddress {
58 type Error = scroll::Error;
59 #[inline]
60 fn try_into_ctx(self, buf: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> {
61 buf.pwrite(self.as_slice(), 0)
62 }
63}
64impl Deref for MACAddress {
65 type Target = [u8; 6];
66 fn deref(&self) -> &Self::Target {
67 &self.0
68 }
69}
70impl DerefMut for MACAddress {
71 fn deref_mut(&mut self) -> &mut Self::Target {
72 &mut self.0
73 }
74}
75impl Index<usize> for MACAddress {
76 type Output = u8;
77 fn index(&self, index: usize) -> &Self::Output {
78 &self.0[index]
79 }
80}
81impl IndexMut<usize> for MACAddress {
82 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
83 &mut self.0[index]
84 }
85}
86impl Debug for MACAddress {
87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 <Self as core::fmt::Display>::fmt(&self, f)
89 }
90}
91impl Display for MACAddress {
92 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93 f.write_fmt(format_args!(
94 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
95 self[0], self[1], self[2], self[3], self[4], self[5]
96 ))
97 }
98}
99#[cfg(feature = "defmt")]
100impl defmt::Format for MACAddress {
101 fn format(&self, fmt: defmt::Formatter) {
102 defmt::write!(
103 fmt,
104 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
105 self[0],
106 self[1],
107 self[2],
108 self[3],
109 self[4],
110 self[5]
111 )
112 }
113}