tpm2_protocol/macro/
integer.rs1#[macro_export]
6macro_rules! integer {
7 ($name:ident, $raw:ty, $bytes:expr) => {
8 #[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
9 #[repr(transparent)]
10 pub struct $name([u8; $bytes]);
11
12 impl $name {
13 #[must_use]
14 pub const fn new(value: $raw) -> Self {
15 Self(value.to_be_bytes())
16 }
17
18 #[must_use]
19 pub const fn value(self) -> $raw {
20 <$raw>::from_be_bytes(self.0)
21 }
22
23 #[must_use]
24 pub const fn get(&self) -> $raw {
25 <$raw>::from_be_bytes(self.0)
26 }
27
28 pub const fn set(&mut self, value: $raw) {
29 self.0 = value.to_be_bytes();
30 }
31
32 #[must_use]
33 pub const fn as_bytes(&self) -> &[u8; $bytes] {
34 &self.0
35 }
36
37 #[must_use]
38 pub fn as_bytes_mut(&mut self) -> &mut [u8; $bytes] {
39 &mut self.0
40 }
41
42 #[must_use]
43 pub fn to_be_bytes(self) -> [u8; $bytes] {
44 self.0
45 }
46
47 #[must_use]
48 pub const fn from_be_bytes(bytes: [u8; $bytes]) -> Self {
49 Self(bytes)
50 }
51
52 pub fn cast(buf: &[u8]) -> $crate::TpmResult<&Self> {
61 let _ = $crate::TpmWireBytes::<$bytes>::cast(buf)?;
62
63 Ok(unsafe { Self::cast_unchecked(buf) })
66 }
67
68 #[must_use]
76 pub unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
77 let ptr = buf.as_ptr().cast::<Self>();
78
79 unsafe { &*ptr }
82 }
83
84 pub fn cast_mut(buf: &mut [u8]) -> $crate::TpmResult<&mut Self> {
93 let _ = $crate::TpmWireBytes::<$bytes>::cast_mut(buf)?;
94
95 Ok(unsafe { Self::cast_mut_unchecked(buf) })
98 }
99
100 #[must_use]
109 pub unsafe fn cast_mut_unchecked(buf: &mut [u8]) -> &mut Self {
110 let ptr = buf.as_mut_ptr().cast::<Self>();
111
112 unsafe { &mut *ptr }
115 }
116 }
117
118 impl core::fmt::Debug for $name {
119 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
120 f.debug_tuple(stringify!($name)).field(&self.get()).finish()
121 }
122 }
123
124 impl core::cmp::PartialOrd for $name {
125 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
126 Some(self.cmp(other))
127 }
128 }
129
130 impl core::cmp::Ord for $name {
131 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
132 self.get().cmp(&other.get())
133 }
134 }
135
136 impl From<$raw> for $name {
137 fn from(value: $raw) -> Self {
138 Self::new(value)
139 }
140 }
141
142 impl From<$name> for $raw {
143 fn from(value: $name) -> $raw {
144 value.value()
145 }
146 }
147
148 impl core::fmt::Display for $name {
149 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
150 core::fmt::Display::fmt(&self.get(), f)
151 }
152 }
153
154 impl core::fmt::LowerHex for $name {
155 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
156 core::fmt::LowerHex::fmt(&self.get(), f)
157 }
158 }
159
160 impl core::fmt::UpperHex for $name {
161 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162 core::fmt::UpperHex::fmt(&self.get(), f)
163 }
164 }
165
166 impl $crate::TpmSized for $name {
167 const SIZE: usize = $bytes;
168 fn len(&self) -> usize {
169 Self::SIZE
170 }
171 }
172
173 impl $crate::TpmMarshal for $name {
174 fn marshal(&self, writer: &mut $crate::TpmWriter) -> $crate::TpmResult<()> {
175 writer.write_bytes(self.as_bytes())
176 }
177 }
178
179 impl $crate::TpmUnmarshal for $name {
180 fn unmarshal(buf: &[u8]) -> $crate::TpmResult<(Self, &[u8])> {
181 let size = core::mem::size_of::<$raw>();
182 let bytes = buf.get(..size).ok_or($crate::TpmError::UnexpectedEnd(
183 $crate::TpmErrorValue::new(0).size(size, buf.len()),
184 ))?;
185 let array = bytes.try_into().map_err(|_| {
186 $crate::TpmError::UnexpectedEnd(
187 $crate::TpmErrorValue::new(0).size(size, buf.len()),
188 )
189 })?;
190 let val = Self::from_be_bytes(array);
191 Ok((val, &buf[size..]))
192 }
193 }
194
195 impl $crate::TpmCast for $name {
196 fn cast(buf: &[u8]) -> $crate::TpmResult<&Self> {
197 Self::cast(buf)
198 }
199
200 unsafe fn cast_unchecked(buf: &[u8]) -> &Self {
201 unsafe { Self::cast_unchecked(buf) }
203 }
204 }
205
206 impl $crate::TpmCastMut for $name {
207 fn cast_mut(buf: &mut [u8]) -> $crate::TpmResult<&mut Self> {
208 Self::cast_mut(buf)
209 }
210
211 unsafe fn cast_mut_unchecked(buf: &mut [u8]) -> &mut Self {
212 unsafe { Self::cast_mut_unchecked(buf) }
214 }
215 }
216
217 impl TryFrom<usize> for $name
218 where
219 $raw: TryFrom<usize>,
220 {
221 type Error = <$raw as TryFrom<usize>>::Error;
222 fn try_from(value: usize) -> Result<Self, Self::Error> {
223 <$raw>::try_from(value).map(Self::new)
224 }
225 }
226 };
227}