spinel_pack/
eui.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::fmt::{Debug, Display, Error, Formatter};
6use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, Unaligned};
7
8/// Error type indicating that the given slice was not the expected size.
9#[derive(Debug, Eq, PartialEq, Hash, thiserror::Error)]
10pub struct WrongSize;
11
12impl Display for WrongSize {
13    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
14        <Self as Debug>::fmt(self, f)
15    }
16}
17
18/// Data type representing a EUI64 address.
19#[derive(
20    Debug, Eq, PartialEq, Hash, Copy, Clone, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned,
21)]
22#[repr(C)]
23#[derive(Default)]
24pub struct EUI64(pub [u8; 8]);
25
26/// Converts a borrowed EUI64 into a borrowed byte slice.
27impl<'a> std::convert::From<&'a EUI64> for &'a [u8] {
28    fn from(val: &'a EUI64) -> Self {
29        &val.0
30    }
31}
32
33/// Converts a borrowed byte slice into a borrowed EUI64 reference.
34/// Will panic if the length of the slice is not exactly 8 bytes.
35impl<'a> std::convert::TryInto<&'a EUI64> for &'a [u8] {
36    type Error = WrongSize;
37
38    fn try_into(self) -> Result<&'a EUI64, Self::Error> {
39        Ref::<_, EUI64>::from_bytes(self)
40            .map_err(Into::into)
41            .map_err(|_: zerocopy::SizeError<_, _>| WrongSize)
42            .map(Ref::into_ref)
43    }
44}
45
46/// Data type representing a EUI48 address.
47#[derive(
48    Debug, Eq, PartialEq, Hash, Copy, Clone, KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned,
49)]
50#[repr(C)]
51#[derive(Default)]
52pub struct EUI48(pub [u8; 6]);
53
54/// Converts a borrowed EUI48 into a borrowed byte slice.
55impl<'a> std::convert::From<&'a EUI48> for &'a [u8] {
56    fn from(val: &'a EUI48) -> Self {
57        &val.0
58    }
59}
60
61/// Converts a borrowed byte slice into a borrowed EUI48 reference.
62/// Will panic if the length of the slice is not exactly 6 bytes.
63impl<'a> std::convert::TryInto<&'a EUI48> for &'a [u8] {
64    type Error = WrongSize;
65
66    fn try_into(self) -> Result<&'a EUI48, Self::Error> {
67        Ref::<_, EUI48>::from_bytes(self)
68            .map_err(Into::into)
69            .map_err(|_: zerocopy::SizeError<_, _>| WrongSize)
70            .map(Ref::into_ref)
71    }
72}