tpm2_protocol/basic/
integer.rs1use crate::{TpmMarshal, TpmResult, TpmSized, TpmUnmarshal, TpmWriter};
6use core::{convert::TryFrom, fmt, mem::size_of};
7
8macro_rules! define_integer {
9 ($name:ident, $raw:ty, $bytes:expr) => {
10 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11 #[repr(transparent)]
12 pub struct $name(pub $raw);
13
14 impl $name {
15 #[must_use]
16 pub const fn new(value: $raw) -> Self {
17 Self(value)
18 }
19
20 #[must_use]
21 pub const fn value(self) -> $raw {
22 self.0
23 }
24
25 #[must_use]
26 pub fn to_be_bytes(self) -> [u8; $bytes] {
27 self.0.to_be_bytes()
28 }
29
30 #[must_use]
31 pub fn from_be_bytes(bytes: [u8; $bytes]) -> Self {
32 Self(<$raw>::from_be_bytes(bytes))
33 }
34 }
35
36 impl From<$raw> for $name {
37 fn from(value: $raw) -> Self {
38 Self(value)
39 }
40 }
41
42 impl From<$name> for $raw {
43 fn from(value: $name) -> $raw {
44 value.0
45 }
46 }
47
48 impl fmt::Display for $name {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 fmt::Display::fmt(&self.0, f)
51 }
52 }
53
54 impl fmt::LowerHex for $name {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 fmt::LowerHex::fmt(&self.0, f)
57 }
58 }
59
60 impl fmt::UpperHex for $name {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 fmt::UpperHex::fmt(&self.0, f)
63 }
64 }
65
66 impl TpmSized for $name {
67 const SIZE: usize = size_of::<$raw>();
68 fn len(&self) -> usize {
69 Self::SIZE
70 }
71 }
72
73 impl TpmMarshal for $name {
74 fn marshal(&self, writer: &mut TpmWriter) -> TpmResult<()> {
75 writer.write_bytes(&self.to_be_bytes())
76 }
77 }
78
79 impl TpmUnmarshal for $name {
80 fn unmarshal(buf: &[u8]) -> TpmResult<(Self, &[u8])> {
81 let size = size_of::<$raw>();
82 let bytes = buf
83 .get(..size)
84 .ok_or(crate::TpmProtocolError::UnexpectedEnd)?;
85 let array = bytes
86 .try_into()
87 .map_err(|_| crate::TpmProtocolError::UnexpectedEnd)?;
88 let val = Self::from_be_bytes(array);
89 Ok((val, &buf[size..]))
90 }
91 }
92
93 impl TryFrom<usize> for $name
94 where
95 $raw: TryFrom<usize>,
96 {
97 type Error = <$raw as TryFrom<usize>>::Error;
98 fn try_from(value: usize) -> Result<Self, Self::Error> {
99 <$raw>::try_from(value).map(Self)
100 }
101 }
102 };
103}
104
105define_integer!(Uint8, u8, 1);
106define_integer!(Int8, i8, 1);
107define_integer!(Uint16, u16, 2);
108define_integer!(Uint32, u32, 4);
109define_integer!(Uint64, u64, 8);
110define_integer!(Int32, i32, 4);
111
112pub trait IntegerRepr: Copy {
114 type Wrapper: TpmSized + TpmMarshal + TpmUnmarshal + From<Self> + Into<Self>;
116}
117
118impl IntegerRepr for u8 {
119 type Wrapper = Uint8;
120}
121
122impl IntegerRepr for i8 {
123 type Wrapper = Int8;
124}
125
126impl IntegerRepr for u16 {
127 type Wrapper = Uint16;
128}
129
130impl IntegerRepr for u32 {
131 type Wrapper = Uint32;
132}
133
134impl IntegerRepr for u64 {
135 type Wrapper = Uint64;
136}
137
138impl IntegerRepr for i32 {
139 type Wrapper = Int32;
140}