xref: /aosp_15_r20/external/open-dice/dpe-rs/src/args.rs (revision 60b67249c2e226f42f35cc6cfe66c6048e0bae6b)
1*60b67249SAndroid Build Coastguard Worker // Copyright 2024 Google LLC
2*60b67249SAndroid Build Coastguard Worker //
3*60b67249SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*60b67249SAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*60b67249SAndroid Build Coastguard Worker // the License at
6*60b67249SAndroid Build Coastguard Worker //
7*60b67249SAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*60b67249SAndroid Build Coastguard Worker //
9*60b67249SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*60b67249SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*60b67249SAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*60b67249SAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*60b67249SAndroid Build Coastguard Worker // the License.
14*60b67249SAndroid Build Coastguard Worker 
15*60b67249SAndroid Build Coastguard Worker //! Types related to command arguments.
16*60b67249SAndroid Build Coastguard Worker 
17*60b67249SAndroid Build Coastguard Worker use crate::error::{DpeResult, ErrCode};
18*60b67249SAndroid Build Coastguard Worker use crate::memory::SizedMessage;
19*60b67249SAndroid Build Coastguard Worker use heapless::FnvIndexMap;
20*60b67249SAndroid Build Coastguard Worker use log::error;
21*60b67249SAndroid Build Coastguard Worker 
22*60b67249SAndroid Build Coastguard Worker /// Represents the numeric identifier of a command or response argument.
23*60b67249SAndroid Build Coastguard Worker pub type ArgId = u32;
24*60b67249SAndroid Build Coastguard Worker 
25*60b67249SAndroid Build Coastguard Worker /// Represents the type of a command or response argument.
26*60b67249SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
27*60b67249SAndroid Build Coastguard Worker pub enum ArgTypeSelector {
28*60b67249SAndroid Build Coastguard Worker     /// Indicates an argument was not recognized, so its type is unknown.
29*60b67249SAndroid Build Coastguard Worker     #[default]
30*60b67249SAndroid Build Coastguard Worker     Unknown,
31*60b67249SAndroid Build Coastguard Worker     /// Indicates an argument is encoded as a CBOR byte string.
32*60b67249SAndroid Build Coastguard Worker     Bytes,
33*60b67249SAndroid Build Coastguard Worker     /// Indicates an argument is encoded as a CBOR unsigned integer.
34*60b67249SAndroid Build Coastguard Worker     Int,
35*60b67249SAndroid Build Coastguard Worker     /// Indicates an argument is encoded as a CBOR true or false simple value.
36*60b67249SAndroid Build Coastguard Worker     Bool,
37*60b67249SAndroid Build Coastguard Worker     /// Indicates an argument needs additional custom decoding.
38*60b67249SAndroid Build Coastguard Worker     Other,
39*60b67249SAndroid Build Coastguard Worker }
40*60b67249SAndroid Build Coastguard Worker 
41*60b67249SAndroid Build Coastguard Worker /// Represents a command or response argument value.
42*60b67249SAndroid Build Coastguard Worker #[derive(Clone, Debug, Eq, PartialEq, Hash)]
43*60b67249SAndroid Build Coastguard Worker pub enum ArgValue<'a> {
44*60b67249SAndroid Build Coastguard Worker     /// This instantiation borrows a slice of a message buffer that was decoded
45*60b67249SAndroid Build Coastguard Worker     /// as a CBOR byte string. The slice needs to live at least as long as
46*60b67249SAndroid Build Coastguard Worker     /// this.
47*60b67249SAndroid Build Coastguard Worker     BytesArg(&'a [u8]),
48*60b67249SAndroid Build Coastguard Worker     /// This instantiation contains a decoded CBOR unsigned integer.
49*60b67249SAndroid Build Coastguard Worker     IntArg(u64),
50*60b67249SAndroid Build Coastguard Worker     /// This instantiation contains a decoded CBOR boolean value.
51*60b67249SAndroid Build Coastguard Worker     BoolArg(bool),
52*60b67249SAndroid Build Coastguard Worker }
53*60b67249SAndroid Build Coastguard Worker 
54*60b67249SAndroid Build Coastguard Worker impl<'a> ArgValue<'a> {
55*60b67249SAndroid Build Coastguard Worker     /// Creates a new `BytesArg` from a slice, borrowing the slice.
from_slice(value: &'a [u8]) -> Self56*60b67249SAndroid Build Coastguard Worker     pub fn from_slice(value: &'a [u8]) -> Self {
57*60b67249SAndroid Build Coastguard Worker         ArgValue::BytesArg(value)
58*60b67249SAndroid Build Coastguard Worker     }
59*60b67249SAndroid Build Coastguard Worker 
60*60b67249SAndroid Build Coastguard Worker     /// Returns the borrowed slice if this is a BytesArg.
61*60b67249SAndroid Build Coastguard Worker     ///
62*60b67249SAndroid Build Coastguard Worker     /// # Errors
63*60b67249SAndroid Build Coastguard Worker     ///
64*60b67249SAndroid Build Coastguard Worker     /// Returns an InternalError error if this is not a BytesArg.
try_into_slice(&self) -> DpeResult<&'a [u8]>65*60b67249SAndroid Build Coastguard Worker     pub fn try_into_slice(&self) -> DpeResult<&'a [u8]> {
66*60b67249SAndroid Build Coastguard Worker         match self {
67*60b67249SAndroid Build Coastguard Worker             ArgValue::IntArg(_) | ArgValue::BoolArg(_) => {
68*60b67249SAndroid Build Coastguard Worker                 error!("ArgValue::try_info_slice called on {:?}", self);
69*60b67249SAndroid Build Coastguard Worker                 Err(ErrCode::InternalError)
70*60b67249SAndroid Build Coastguard Worker             }
71*60b67249SAndroid Build Coastguard Worker             ArgValue::BytesArg(value) => Ok(value),
72*60b67249SAndroid Build Coastguard Worker         }
73*60b67249SAndroid Build Coastguard Worker     }
74*60b67249SAndroid Build Coastguard Worker 
75*60b67249SAndroid Build Coastguard Worker     /// Returns the value held by an IntArg as a u32.
76*60b67249SAndroid Build Coastguard Worker     ///
77*60b67249SAndroid Build Coastguard Worker     /// # Errors
78*60b67249SAndroid Build Coastguard Worker     ///
79*60b67249SAndroid Build Coastguard Worker     /// Returns an InternalError error if this is not an IntArg.
try_into_u32(&self) -> DpeResult<u32>80*60b67249SAndroid Build Coastguard Worker     pub fn try_into_u32(&self) -> DpeResult<u32> {
81*60b67249SAndroid Build Coastguard Worker         match self {
82*60b67249SAndroid Build Coastguard Worker             ArgValue::IntArg(i) => Ok((*i).try_into()?),
83*60b67249SAndroid Build Coastguard Worker             _ => {
84*60b67249SAndroid Build Coastguard Worker                 error!("ArgValue::try_into_u32 called on {:?}", self);
85*60b67249SAndroid Build Coastguard Worker                 Err(ErrCode::InternalError)
86*60b67249SAndroid Build Coastguard Worker             }
87*60b67249SAndroid Build Coastguard Worker         }
88*60b67249SAndroid Build Coastguard Worker     }
89*60b67249SAndroid Build Coastguard Worker 
90*60b67249SAndroid Build Coastguard Worker     /// Creates a new `IntArg` holding the given u32 `value`.
from_u32(value: u32) -> Self91*60b67249SAndroid Build Coastguard Worker     pub fn from_u32(value: u32) -> Self {
92*60b67249SAndroid Build Coastguard Worker         ArgValue::IntArg(value as u64)
93*60b67249SAndroid Build Coastguard Worker     }
94*60b67249SAndroid Build Coastguard Worker 
95*60b67249SAndroid Build Coastguard Worker     /// Returns the value held by an IntArg as a u64.
96*60b67249SAndroid Build Coastguard Worker     ///
97*60b67249SAndroid Build Coastguard Worker     /// # Errors
98*60b67249SAndroid Build Coastguard Worker     ///
99*60b67249SAndroid Build Coastguard Worker     /// Returns an InternalError error if this is not an IntArg.
try_into_u64(&self) -> DpeResult<u64>100*60b67249SAndroid Build Coastguard Worker     pub fn try_into_u64(&self) -> DpeResult<u64> {
101*60b67249SAndroid Build Coastguard Worker         match self {
102*60b67249SAndroid Build Coastguard Worker             ArgValue::IntArg(i) => Ok(*i),
103*60b67249SAndroid Build Coastguard Worker             _ => {
104*60b67249SAndroid Build Coastguard Worker                 error!("ArgValue::try_into_u64 called on {:?}", self);
105*60b67249SAndroid Build Coastguard Worker                 Err(ErrCode::InternalError)
106*60b67249SAndroid Build Coastguard Worker             }
107*60b67249SAndroid Build Coastguard Worker         }
108*60b67249SAndroid Build Coastguard Worker     }
109*60b67249SAndroid Build Coastguard Worker 
110*60b67249SAndroid Build Coastguard Worker     /// Creates a new `IntArg` holding the given u64 `value`.
from_u64(value: u64) -> Self111*60b67249SAndroid Build Coastguard Worker     pub fn from_u64(value: u64) -> Self {
112*60b67249SAndroid Build Coastguard Worker         ArgValue::IntArg(value)
113*60b67249SAndroid Build Coastguard Worker     }
114*60b67249SAndroid Build Coastguard Worker 
115*60b67249SAndroid Build Coastguard Worker     /// Returns the value held by a BoolArg.
116*60b67249SAndroid Build Coastguard Worker     ///
117*60b67249SAndroid Build Coastguard Worker     /// # Errors
118*60b67249SAndroid Build Coastguard Worker     ///
119*60b67249SAndroid Build Coastguard Worker     /// Returns an InternalError error if this is not a BoolArg.
try_into_bool(&self) -> DpeResult<bool>120*60b67249SAndroid Build Coastguard Worker     pub fn try_into_bool(&self) -> DpeResult<bool> {
121*60b67249SAndroid Build Coastguard Worker         match self {
122*60b67249SAndroid Build Coastguard Worker             ArgValue::BoolArg(b) => Ok(*b),
123*60b67249SAndroid Build Coastguard Worker             _ => {
124*60b67249SAndroid Build Coastguard Worker                 error!("ArgValue::try_into_bool called on {:?}", self);
125*60b67249SAndroid Build Coastguard Worker                 Err(ErrCode::InternalError)
126*60b67249SAndroid Build Coastguard Worker             }
127*60b67249SAndroid Build Coastguard Worker         }
128*60b67249SAndroid Build Coastguard Worker     }
129*60b67249SAndroid Build Coastguard Worker 
130*60b67249SAndroid Build Coastguard Worker     /// Creates a new `BoolArg` holding the given `value`.
from_bool(value: bool) -> Self131*60b67249SAndroid Build Coastguard Worker     pub fn from_bool(value: bool) -> Self {
132*60b67249SAndroid Build Coastguard Worker         ArgValue::BoolArg(value)
133*60b67249SAndroid Build Coastguard Worker     }
134*60b67249SAndroid Build Coastguard Worker }
135*60b67249SAndroid Build Coastguard Worker 
136*60b67249SAndroid Build Coastguard Worker impl<'a, const S: usize> From<&'a SizedMessage<S>> for ArgValue<'a> {
from(message: &'a SizedMessage<S>) -> Self137*60b67249SAndroid Build Coastguard Worker     fn from(message: &'a SizedMessage<S>) -> Self {
138*60b67249SAndroid Build Coastguard Worker         Self::BytesArg(message.as_slice())
139*60b67249SAndroid Build Coastguard Worker     }
140*60b67249SAndroid Build Coastguard Worker }
141*60b67249SAndroid Build Coastguard Worker 
142*60b67249SAndroid Build Coastguard Worker /// Contains a set of command or response arguments in the form of a map from
143*60b67249SAndroid Build Coastguard Worker /// [`ArgId`] to [`ArgValue`].
144*60b67249SAndroid Build Coastguard Worker pub type ArgMap<'a> = FnvIndexMap<ArgId, ArgValue<'a>, 16>;
145*60b67249SAndroid Build Coastguard Worker 
146*60b67249SAndroid Build Coastguard Worker /// Contains a set of argument types in the form of a map from ArgId to
147*60b67249SAndroid Build Coastguard Worker /// [`ArgTypeSelector`].
148*60b67249SAndroid Build Coastguard Worker pub type ArgTypeMap = FnvIndexMap<ArgId, ArgTypeSelector, 16>;
149