tpm2_protocol/macro/
integer.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2// Copyright (c) 2025 Opinsys Oy
3// Copyright (c) 2024-2025 Jarkko Sakkinen
4
5#[macro_export]
6macro_rules! integer {
7    ($name:ident, $raw:ty, $bytes:expr) => {
8        #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9        #[repr(transparent)]
10        pub struct $name(pub $raw);
11
12        impl $name {
13            #[must_use]
14            pub const fn new(value: $raw) -> Self {
15                Self(value)
16            }
17
18            #[must_use]
19            pub const fn value(self) -> $raw {
20                self.0
21            }
22
23            #[must_use]
24            pub fn to_be_bytes(self) -> [u8; $bytes] {
25                self.0.to_be_bytes()
26            }
27
28            #[must_use]
29            pub fn from_be_bytes(bytes: [u8; $bytes]) -> Self {
30                Self(<$raw>::from_be_bytes(bytes))
31            }
32        }
33
34        impl From<$raw> for $name {
35            fn from(value: $raw) -> Self {
36                Self(value)
37            }
38        }
39
40        impl From<$name> for $raw {
41            fn from(value: $name) -> $raw {
42                value.0
43            }
44        }
45
46        impl core::fmt::Display for $name {
47            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
48                core::fmt::Display::fmt(&self.0, f)
49            }
50        }
51
52        impl core::fmt::LowerHex for $name {
53            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54                core::fmt::LowerHex::fmt(&self.0, f)
55            }
56        }
57
58        impl core::fmt::UpperHex for $name {
59            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60                core::fmt::UpperHex::fmt(&self.0, f)
61            }
62        }
63
64        impl $crate::TpmSized for $name {
65            const SIZE: usize = core::mem::size_of::<$raw>();
66            fn len(&self) -> usize {
67                Self::SIZE
68            }
69        }
70
71        impl $crate::TpmMarshal for $name {
72            fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
73                writer.write_bytes(&self.to_be_bytes())
74            }
75        }
76
77        impl $crate::TpmUnmarshal for $name {
78            fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
79                let size = core::mem::size_of::<$raw>();
80                let bytes = buf
81                    .get(..size)
82                    .ok_or($crate::TpmProtocolError::UnexpectedEnd)?;
83                let array = bytes
84                    .try_into()
85                    .map_err(|_| $crate::TpmProtocolError::UnexpectedEnd)?;
86                let val = Self::from_be_bytes(array);
87                Ok((val, &buf[size..]))
88            }
89        }
90
91        impl TryFrom<usize> for $name
92        where
93            $raw: TryFrom<usize>,
94        {
95            type Error = <$raw as TryFrom<usize>>::Error;
96            fn try_from(value: usize) -> Result<Self, Self::Error> {
97                <$raw>::try_from(value).map(Self)
98            }
99        }
100    };
101}