xref: /aosp_15_r20/system/keymint/wire/src/lib.rs (revision 9860b7637a5f185913c70aa0caabe3ecb78441e4)
1*9860b763SAndroid Build Coastguard Worker // Copyright 2022, The Android Open Source Project
2*9860b763SAndroid Build Coastguard Worker //
3*9860b763SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9860b763SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9860b763SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9860b763SAndroid Build Coastguard Worker //
7*9860b763SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*9860b763SAndroid Build Coastguard Worker //
9*9860b763SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9860b763SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9860b763SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9860b763SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9860b763SAndroid Build Coastguard Worker // limitations under the License.
14*9860b763SAndroid Build Coastguard Worker 
15*9860b763SAndroid Build Coastguard Worker //! Types and macros for communication between HAL and TA
16*9860b763SAndroid Build Coastguard Worker 
17*9860b763SAndroid Build Coastguard Worker // Allow missing docs in this crate as the types here are generally 1:1 with the HAL
18*9860b763SAndroid Build Coastguard Worker // interface definitions.
19*9860b763SAndroid Build Coastguard Worker #![allow(missing_docs)]
20*9860b763SAndroid Build Coastguard Worker #![no_std]
21*9860b763SAndroid Build Coastguard Worker extern crate alloc;
22*9860b763SAndroid Build Coastguard Worker 
23*9860b763SAndroid Build Coastguard Worker use alloc::{
24*9860b763SAndroid Build Coastguard Worker     format,
25*9860b763SAndroid Build Coastguard Worker     string::{String, ToString},
26*9860b763SAndroid Build Coastguard Worker     vec::Vec,
27*9860b763SAndroid Build Coastguard Worker };
28*9860b763SAndroid Build Coastguard Worker use coset::TaggedCborSerializable;
29*9860b763SAndroid Build Coastguard Worker 
30*9860b763SAndroid Build Coastguard Worker /// Re-export of crate used for CBOR encoding.
31*9860b763SAndroid Build Coastguard Worker pub use ciborium as cbor;
32*9860b763SAndroid Build Coastguard Worker /// Re-export of crate used for COSE encoding.
33*9860b763SAndroid Build Coastguard Worker pub use coset;
34*9860b763SAndroid Build Coastguard Worker 
35*9860b763SAndroid Build Coastguard Worker pub mod keymint;
36*9860b763SAndroid Build Coastguard Worker pub mod legacy;
37*9860b763SAndroid Build Coastguard Worker pub mod rpc;
38*9860b763SAndroid Build Coastguard Worker pub mod secureclock;
39*9860b763SAndroid Build Coastguard Worker pub mod sharedsecret;
40*9860b763SAndroid Build Coastguard Worker pub mod types;
41*9860b763SAndroid Build Coastguard Worker pub use types::*;
42*9860b763SAndroid Build Coastguard Worker 
43*9860b763SAndroid Build Coastguard Worker #[cfg(test)]
44*9860b763SAndroid Build Coastguard Worker mod tests;
45*9860b763SAndroid Build Coastguard Worker 
46*9860b763SAndroid Build Coastguard Worker /// Macro that emits an implementation of `TryFrom<i32>` for an enum type that has `[derive(N)]`
47*9860b763SAndroid Build Coastguard Worker /// attached to it.  The implementation assumes that `ValueNotRecognized` has a variant with the
48*9860b763SAndroid Build Coastguard Worker /// same name as the enum.
49*9860b763SAndroid Build Coastguard Worker #[macro_export]
50*9860b763SAndroid Build Coastguard Worker macro_rules! try_from_n {
51*9860b763SAndroid Build Coastguard Worker     { $ename:ident } => {
52*9860b763SAndroid Build Coastguard Worker         impl core::convert::TryFrom<i32> for $ename {
53*9860b763SAndroid Build Coastguard Worker             type Error = $crate::ValueNotRecognized;
54*9860b763SAndroid Build Coastguard Worker             fn try_from(value: i32) -> Result<Self, Self::Error> {
55*9860b763SAndroid Build Coastguard Worker                 Self::n(value).ok_or($crate::ValueNotRecognized::$ename)
56*9860b763SAndroid Build Coastguard Worker             }
57*9860b763SAndroid Build Coastguard Worker         }
58*9860b763SAndroid Build Coastguard Worker     };
59*9860b763SAndroid Build Coastguard Worker }
60*9860b763SAndroid Build Coastguard Worker 
61*9860b763SAndroid Build Coastguard Worker /// Function that mimics `vec![<val>; <len>]` but which detects allocation failure with the given
62*9860b763SAndroid Build Coastguard Worker /// error.
vec_try_fill_with_alloc_err<T: Clone, E>( elem: T, len: usize, alloc_err: fn() -> E, ) -> Result<Vec<T>, E>63*9860b763SAndroid Build Coastguard Worker pub fn vec_try_fill_with_alloc_err<T: Clone, E>(
64*9860b763SAndroid Build Coastguard Worker     elem: T,
65*9860b763SAndroid Build Coastguard Worker     len: usize,
66*9860b763SAndroid Build Coastguard Worker     alloc_err: fn() -> E,
67*9860b763SAndroid Build Coastguard Worker ) -> Result<Vec<T>, E> {
68*9860b763SAndroid Build Coastguard Worker     let mut v = alloc::vec::Vec::new();
69*9860b763SAndroid Build Coastguard Worker     v.try_reserve(len).map_err(|_e| alloc_err())?;
70*9860b763SAndroid Build Coastguard Worker     v.resize(len, elem);
71*9860b763SAndroid Build Coastguard Worker     Ok(v)
72*9860b763SAndroid Build Coastguard Worker }
73*9860b763SAndroid Build Coastguard Worker 
74*9860b763SAndroid Build Coastguard Worker /// Function that mimics `vec![x1, x2, x3, x4]` but which detects allocation failure with the given
75*9860b763SAndroid Build Coastguard Worker /// error.
vec_try4_with_alloc_err<T: Clone, E>( x1: T, x2: T, x3: T, x4: T, alloc_err: fn() -> E, ) -> Result<Vec<T>, E>76*9860b763SAndroid Build Coastguard Worker pub fn vec_try4_with_alloc_err<T: Clone, E>(
77*9860b763SAndroid Build Coastguard Worker     x1: T,
78*9860b763SAndroid Build Coastguard Worker     x2: T,
79*9860b763SAndroid Build Coastguard Worker     x3: T,
80*9860b763SAndroid Build Coastguard Worker     x4: T,
81*9860b763SAndroid Build Coastguard Worker     alloc_err: fn() -> E,
82*9860b763SAndroid Build Coastguard Worker ) -> Result<Vec<T>, E> {
83*9860b763SAndroid Build Coastguard Worker     let mut v = alloc::vec::Vec::new();
84*9860b763SAndroid Build Coastguard Worker     match v.try_reserve(4) {
85*9860b763SAndroid Build Coastguard Worker         Err(_e) => Err(alloc_err()),
86*9860b763SAndroid Build Coastguard Worker         Ok(_) => {
87*9860b763SAndroid Build Coastguard Worker             v.push(x1);
88*9860b763SAndroid Build Coastguard Worker             v.push(x2);
89*9860b763SAndroid Build Coastguard Worker             v.push(x3);
90*9860b763SAndroid Build Coastguard Worker             v.push(x4);
91*9860b763SAndroid Build Coastguard Worker             Ok(v)
92*9860b763SAndroid Build Coastguard Worker         }
93*9860b763SAndroid Build Coastguard Worker     }
94*9860b763SAndroid Build Coastguard Worker }
95*9860b763SAndroid Build Coastguard Worker 
96*9860b763SAndroid Build Coastguard Worker /// Function that mimics `vec![x1, x2, x3]` but which detects allocation failure with the given
97*9860b763SAndroid Build Coastguard Worker /// error.
vec_try3_with_alloc_err<T: Clone, E>( x1: T, x2: T, x3: T, alloc_err: fn() -> E, ) -> Result<Vec<T>, E>98*9860b763SAndroid Build Coastguard Worker pub fn vec_try3_with_alloc_err<T: Clone, E>(
99*9860b763SAndroid Build Coastguard Worker     x1: T,
100*9860b763SAndroid Build Coastguard Worker     x2: T,
101*9860b763SAndroid Build Coastguard Worker     x3: T,
102*9860b763SAndroid Build Coastguard Worker     alloc_err: fn() -> E,
103*9860b763SAndroid Build Coastguard Worker ) -> Result<Vec<T>, E> {
104*9860b763SAndroid Build Coastguard Worker     let mut v = alloc::vec::Vec::new();
105*9860b763SAndroid Build Coastguard Worker     match v.try_reserve(3) {
106*9860b763SAndroid Build Coastguard Worker         Err(_e) => Err(alloc_err()),
107*9860b763SAndroid Build Coastguard Worker         Ok(_) => {
108*9860b763SAndroid Build Coastguard Worker             v.push(x1);
109*9860b763SAndroid Build Coastguard Worker             v.push(x2);
110*9860b763SAndroid Build Coastguard Worker             v.push(x3);
111*9860b763SAndroid Build Coastguard Worker             Ok(v)
112*9860b763SAndroid Build Coastguard Worker         }
113*9860b763SAndroid Build Coastguard Worker     }
114*9860b763SAndroid Build Coastguard Worker }
115*9860b763SAndroid Build Coastguard Worker 
116*9860b763SAndroid Build Coastguard Worker /// Function that mimics `vec![x1, x2]` but which detects allocation failure with the given error.
vec_try2_with_alloc_err<T: Clone, E>( x1: T, x2: T, alloc_err: fn() -> E, ) -> Result<Vec<T>, E>117*9860b763SAndroid Build Coastguard Worker pub fn vec_try2_with_alloc_err<T: Clone, E>(
118*9860b763SAndroid Build Coastguard Worker     x1: T,
119*9860b763SAndroid Build Coastguard Worker     x2: T,
120*9860b763SAndroid Build Coastguard Worker     alloc_err: fn() -> E,
121*9860b763SAndroid Build Coastguard Worker ) -> Result<Vec<T>, E> {
122*9860b763SAndroid Build Coastguard Worker     let mut v = alloc::vec::Vec::new();
123*9860b763SAndroid Build Coastguard Worker     match v.try_reserve(2) {
124*9860b763SAndroid Build Coastguard Worker         Err(_e) => Err(alloc_err()),
125*9860b763SAndroid Build Coastguard Worker         Ok(_) => {
126*9860b763SAndroid Build Coastguard Worker             v.push(x1);
127*9860b763SAndroid Build Coastguard Worker             v.push(x2);
128*9860b763SAndroid Build Coastguard Worker             Ok(v)
129*9860b763SAndroid Build Coastguard Worker         }
130*9860b763SAndroid Build Coastguard Worker     }
131*9860b763SAndroid Build Coastguard Worker }
132*9860b763SAndroid Build Coastguard Worker 
133*9860b763SAndroid Build Coastguard Worker /// Function that mimics `vec![x1]` but which detects allocation failure with the given error.
vec_try1_with_alloc_err<T: Clone, E>(x1: T, alloc_err: fn() -> E) -> Result<Vec<T>, E>134*9860b763SAndroid Build Coastguard Worker pub fn vec_try1_with_alloc_err<T: Clone, E>(x1: T, alloc_err: fn() -> E) -> Result<Vec<T>, E> {
135*9860b763SAndroid Build Coastguard Worker     let mut v = alloc::vec::Vec::new();
136*9860b763SAndroid Build Coastguard Worker     match v.try_reserve(1) {
137*9860b763SAndroid Build Coastguard Worker         Err(_e) => Err(alloc_err()),
138*9860b763SAndroid Build Coastguard Worker         Ok(_) => {
139*9860b763SAndroid Build Coastguard Worker             v.push(x1);
140*9860b763SAndroid Build Coastguard Worker             Ok(v)
141*9860b763SAndroid Build Coastguard Worker         }
142*9860b763SAndroid Build Coastguard Worker     }
143*9860b763SAndroid Build Coastguard Worker }
144*9860b763SAndroid Build Coastguard Worker 
145*9860b763SAndroid Build Coastguard Worker /// Macro that mimics `vec!` but which detects allocation failure.
146*9860b763SAndroid Build Coastguard Worker #[macro_export]
147*9860b763SAndroid Build Coastguard Worker macro_rules! vec_try {
148*9860b763SAndroid Build Coastguard Worker     { $elem:expr ; $len:expr } => {
149*9860b763SAndroid Build Coastguard Worker         $crate::vec_try_fill_with_alloc_err($elem, $len, || $crate::CborError::AllocationFailed)
150*9860b763SAndroid Build Coastguard Worker     };
151*9860b763SAndroid Build Coastguard Worker     { $x1:expr, $x2:expr, $x3:expr, $x4:expr $(,)? } => {
152*9860b763SAndroid Build Coastguard Worker         $crate::vec_try4_with_alloc_err($x1, $x2, $x3, $x4, || $crate::CborError::AllocationFailed)
153*9860b763SAndroid Build Coastguard Worker     };
154*9860b763SAndroid Build Coastguard Worker     { $x1:expr, $x2:expr, $x3:expr $(,)? } => {
155*9860b763SAndroid Build Coastguard Worker         $crate::vec_try3_with_alloc_err($x1, $x2, $x3, || $crate::CborError::AllocationFailed)
156*9860b763SAndroid Build Coastguard Worker     };
157*9860b763SAndroid Build Coastguard Worker     { $x1:expr, $x2:expr $(,)? } => {
158*9860b763SAndroid Build Coastguard Worker         $crate::vec_try2_with_alloc_err($x1, $x2, || $crate::CborError::AllocationFailed)
159*9860b763SAndroid Build Coastguard Worker     };
160*9860b763SAndroid Build Coastguard Worker     { $x1:expr $(,)? } => {
161*9860b763SAndroid Build Coastguard Worker         $crate::vec_try1_with_alloc_err($x1, || $crate::CborError::AllocationFailed)
162*9860b763SAndroid Build Coastguard Worker     };
163*9860b763SAndroid Build Coastguard Worker }
164*9860b763SAndroid Build Coastguard Worker 
165*9860b763SAndroid Build Coastguard Worker /// Marker structure indicating that the EOF was encountered when reading CBOR data.
166*9860b763SAndroid Build Coastguard Worker #[derive(Debug)]
167*9860b763SAndroid Build Coastguard Worker pub struct EndOfFile;
168*9860b763SAndroid Build Coastguard Worker 
169*9860b763SAndroid Build Coastguard Worker /// Error type for failures in encoding or decoding CBOR types.
170*9860b763SAndroid Build Coastguard Worker pub enum CborError {
171*9860b763SAndroid Build Coastguard Worker     /// CBOR decoding failure.
172*9860b763SAndroid Build Coastguard Worker     DecodeFailed(cbor::de::Error<EndOfFile>),
173*9860b763SAndroid Build Coastguard Worker     /// CBOR encoding failure.
174*9860b763SAndroid Build Coastguard Worker     EncodeFailed,
175*9860b763SAndroid Build Coastguard Worker     /// CBOR input had extra data.
176*9860b763SAndroid Build Coastguard Worker     ExtraneousData,
177*9860b763SAndroid Build Coastguard Worker     /// Integer value outside expected range.
178*9860b763SAndroid Build Coastguard Worker     OutOfRangeIntegerValue,
179*9860b763SAndroid Build Coastguard Worker     /// Integer value that doesn't match expected set of allowed enum values.
180*9860b763SAndroid Build Coastguard Worker     NonEnumValue,
181*9860b763SAndroid Build Coastguard Worker     /// Unexpected CBOR item encountered (got, want).
182*9860b763SAndroid Build Coastguard Worker     UnexpectedItem(&'static str, &'static str),
183*9860b763SAndroid Build Coastguard Worker     /// Value conversion failure.
184*9860b763SAndroid Build Coastguard Worker     InvalidValue,
185*9860b763SAndroid Build Coastguard Worker     /// Allocation failure.
186*9860b763SAndroid Build Coastguard Worker     AllocationFailed,
187*9860b763SAndroid Build Coastguard Worker }
188*9860b763SAndroid Build Coastguard Worker 
189*9860b763SAndroid Build Coastguard Worker // Can only implement `Into` due to orphan trait rule.
190*9860b763SAndroid Build Coastguard Worker #[allow(clippy::from_over_into)]
191*9860b763SAndroid Build Coastguard Worker impl Into<coset::CoseError> for CborError {
into(self) -> coset::CoseError192*9860b763SAndroid Build Coastguard Worker     fn into(self) -> coset::CoseError {
193*9860b763SAndroid Build Coastguard Worker         match self {
194*9860b763SAndroid Build Coastguard Worker             CborError::DecodeFailed(inner) => coset::CoseError::DecodeFailed(match inner {
195*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::Io(_io) => cbor::de::Error::Io(coset::EndOfFile),
196*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::Syntax(v) => cbor::de::Error::Syntax(v),
197*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::Semantic(sz, msg) => cbor::de::Error::Semantic(sz, msg),
198*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::RecursionLimitExceeded => cbor::de::Error::RecursionLimitExceeded,
199*9860b763SAndroid Build Coastguard Worker             }),
200*9860b763SAndroid Build Coastguard Worker             CborError::EncodeFailed => coset::CoseError::EncodeFailed,
201*9860b763SAndroid Build Coastguard Worker             CborError::ExtraneousData => coset::CoseError::ExtraneousData,
202*9860b763SAndroid Build Coastguard Worker             CborError::OutOfRangeIntegerValue => coset::CoseError::OutOfRangeIntegerValue,
203*9860b763SAndroid Build Coastguard Worker             CborError::NonEnumValue => coset::CoseError::OutOfRangeIntegerValue,
204*9860b763SAndroid Build Coastguard Worker             CborError::UnexpectedItem(got, want) => coset::CoseError::UnexpectedItem(got, want),
205*9860b763SAndroid Build Coastguard Worker             CborError::InvalidValue => coset::CoseError::EncodeFailed,
206*9860b763SAndroid Build Coastguard Worker             CborError::AllocationFailed => coset::CoseError::EncodeFailed,
207*9860b763SAndroid Build Coastguard Worker         }
208*9860b763SAndroid Build Coastguard Worker     }
209*9860b763SAndroid Build Coastguard Worker }
210*9860b763SAndroid Build Coastguard Worker 
211*9860b763SAndroid Build Coastguard Worker impl<T> From<cbor::de::Error<T>> for CborError {
from(e: cbor::de::Error<T>) -> Self212*9860b763SAndroid Build Coastguard Worker     fn from(e: cbor::de::Error<T>) -> Self {
213*9860b763SAndroid Build Coastguard Worker         // Make sure we use our [`EndOfFile`] marker.
214*9860b763SAndroid Build Coastguard Worker         use cbor::de::Error::{Io, RecursionLimitExceeded, Semantic, Syntax};
215*9860b763SAndroid Build Coastguard Worker         let e = match e {
216*9860b763SAndroid Build Coastguard Worker             Io(_) => Io(EndOfFile),
217*9860b763SAndroid Build Coastguard Worker             Syntax(x) => Syntax(x),
218*9860b763SAndroid Build Coastguard Worker             Semantic(a, b) => Semantic(a, b),
219*9860b763SAndroid Build Coastguard Worker             RecursionLimitExceeded => RecursionLimitExceeded,
220*9860b763SAndroid Build Coastguard Worker         };
221*9860b763SAndroid Build Coastguard Worker         CborError::DecodeFailed(e)
222*9860b763SAndroid Build Coastguard Worker     }
223*9860b763SAndroid Build Coastguard Worker }
224*9860b763SAndroid Build Coastguard Worker 
225*9860b763SAndroid Build Coastguard Worker impl<T> From<cbor::ser::Error<T>> for CborError {
from(_e: cbor::ser::Error<T>) -> Self226*9860b763SAndroid Build Coastguard Worker     fn from(_e: cbor::ser::Error<T>) -> Self {
227*9860b763SAndroid Build Coastguard Worker         CborError::EncodeFailed
228*9860b763SAndroid Build Coastguard Worker     }
229*9860b763SAndroid Build Coastguard Worker }
230*9860b763SAndroid Build Coastguard Worker 
231*9860b763SAndroid Build Coastguard Worker impl From<cbor::value::Error> for CborError {
from(_e: cbor::value::Error) -> Self232*9860b763SAndroid Build Coastguard Worker     fn from(_e: cbor::value::Error) -> Self {
233*9860b763SAndroid Build Coastguard Worker         CborError::InvalidValue
234*9860b763SAndroid Build Coastguard Worker     }
235*9860b763SAndroid Build Coastguard Worker }
236*9860b763SAndroid Build Coastguard Worker 
237*9860b763SAndroid Build Coastguard Worker impl From<core::num::TryFromIntError> for CborError {
from(_: core::num::TryFromIntError) -> Self238*9860b763SAndroid Build Coastguard Worker     fn from(_: core::num::TryFromIntError) -> Self {
239*9860b763SAndroid Build Coastguard Worker         CborError::OutOfRangeIntegerValue
240*9860b763SAndroid Build Coastguard Worker     }
241*9860b763SAndroid Build Coastguard Worker }
242*9860b763SAndroid Build Coastguard Worker 
243*9860b763SAndroid Build Coastguard Worker impl From<coset::CoseError> for CborError {
from(e: coset::CoseError) -> Self244*9860b763SAndroid Build Coastguard Worker     fn from(e: coset::CoseError) -> Self {
245*9860b763SAndroid Build Coastguard Worker         match e {
246*9860b763SAndroid Build Coastguard Worker             coset::CoseError::DecodeFailed(inner) => CborError::DecodeFailed(match inner {
247*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::Io(_io) => cbor::de::Error::Io(EndOfFile),
248*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::Syntax(v) => cbor::de::Error::Syntax(v),
249*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::Semantic(sz, msg) => cbor::de::Error::Semantic(sz, msg),
250*9860b763SAndroid Build Coastguard Worker                 cbor::de::Error::RecursionLimitExceeded => cbor::de::Error::RecursionLimitExceeded,
251*9860b763SAndroid Build Coastguard Worker             }),
252*9860b763SAndroid Build Coastguard Worker             coset::CoseError::EncodeFailed => CborError::EncodeFailed,
253*9860b763SAndroid Build Coastguard Worker             coset::CoseError::ExtraneousData => CborError::ExtraneousData,
254*9860b763SAndroid Build Coastguard Worker             coset::CoseError::OutOfRangeIntegerValue => CborError::OutOfRangeIntegerValue,
255*9860b763SAndroid Build Coastguard Worker             coset::CoseError::UnregisteredIanaValue => CborError::NonEnumValue,
256*9860b763SAndroid Build Coastguard Worker             coset::CoseError::UnregisteredIanaNonPrivateValue => CborError::NonEnumValue,
257*9860b763SAndroid Build Coastguard Worker             coset::CoseError::UnexpectedItem(got, want) => CborError::UnexpectedItem(got, want),
258*9860b763SAndroid Build Coastguard Worker             coset::CoseError::DuplicateMapKey => {
259*9860b763SAndroid Build Coastguard Worker                 CborError::UnexpectedItem("dup map key", "unique keys")
260*9860b763SAndroid Build Coastguard Worker             }
261*9860b763SAndroid Build Coastguard Worker         }
262*9860b763SAndroid Build Coastguard Worker     }
263*9860b763SAndroid Build Coastguard Worker }
264*9860b763SAndroid Build Coastguard Worker 
265*9860b763SAndroid Build Coastguard Worker impl core::fmt::Debug for CborError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result266*9860b763SAndroid Build Coastguard Worker     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
267*9860b763SAndroid Build Coastguard Worker         match self {
268*9860b763SAndroid Build Coastguard Worker             CborError::DecodeFailed(de) => write!(f, "decode CBOR failure: {:?}", de),
269*9860b763SAndroid Build Coastguard Worker             CborError::EncodeFailed => write!(f, "encode CBOR failure"),
270*9860b763SAndroid Build Coastguard Worker             CborError::ExtraneousData => write!(f, "extraneous data in CBOR input"),
271*9860b763SAndroid Build Coastguard Worker             CborError::OutOfRangeIntegerValue => write!(f, "out of range integer value"),
272*9860b763SAndroid Build Coastguard Worker             CborError::NonEnumValue => write!(f, "integer not a valid enum value"),
273*9860b763SAndroid Build Coastguard Worker             CborError::UnexpectedItem(got, want) => write!(f, "got {}, expected {}", got, want),
274*9860b763SAndroid Build Coastguard Worker             CborError::InvalidValue => write!(f, "invalid CBOR value"),
275*9860b763SAndroid Build Coastguard Worker             CborError::AllocationFailed => write!(f, "allocation failed"),
276*9860b763SAndroid Build Coastguard Worker         }
277*9860b763SAndroid Build Coastguard Worker     }
278*9860b763SAndroid Build Coastguard Worker }
279*9860b763SAndroid Build Coastguard Worker 
280*9860b763SAndroid Build Coastguard Worker /// Return an error indicating that an unexpected CBOR type was encountered.
cbor_type_error<T>(value: &cbor::value::Value, want: &'static str) -> Result<T, CborError>281*9860b763SAndroid Build Coastguard Worker pub fn cbor_type_error<T>(value: &cbor::value::Value, want: &'static str) -> Result<T, CborError> {
282*9860b763SAndroid Build Coastguard Worker     use cbor::value::Value;
283*9860b763SAndroid Build Coastguard Worker     let got = match value {
284*9860b763SAndroid Build Coastguard Worker         Value::Integer(_) => "int",
285*9860b763SAndroid Build Coastguard Worker         Value::Bytes(_) => "bstr",
286*9860b763SAndroid Build Coastguard Worker         Value::Text(_) => "tstr",
287*9860b763SAndroid Build Coastguard Worker         Value::Array(_) => "array",
288*9860b763SAndroid Build Coastguard Worker         Value::Map(_) => "map",
289*9860b763SAndroid Build Coastguard Worker         Value::Tag(_, _) => "tag",
290*9860b763SAndroid Build Coastguard Worker         Value::Float(_) => "float",
291*9860b763SAndroid Build Coastguard Worker         Value::Bool(_) => "bool",
292*9860b763SAndroid Build Coastguard Worker         Value::Null => "null",
293*9860b763SAndroid Build Coastguard Worker         _ => "unknown",
294*9860b763SAndroid Build Coastguard Worker     };
295*9860b763SAndroid Build Coastguard Worker     Err(CborError::UnexpectedItem(got, want))
296*9860b763SAndroid Build Coastguard Worker }
297*9860b763SAndroid Build Coastguard Worker 
298*9860b763SAndroid Build Coastguard Worker /// Read a [`cbor::value::Value`] from a byte slice, failing if any extra data remains after the
299*9860b763SAndroid Build Coastguard Worker /// `Value` has been read.
read_to_value(mut slice: &[u8]) -> Result<cbor::value::Value, CborError>300*9860b763SAndroid Build Coastguard Worker pub fn read_to_value(mut slice: &[u8]) -> Result<cbor::value::Value, CborError> {
301*9860b763SAndroid Build Coastguard Worker     let value = cbor::de::from_reader_with_recursion_limit(&mut slice, 16)?;
302*9860b763SAndroid Build Coastguard Worker     if slice.is_empty() {
303*9860b763SAndroid Build Coastguard Worker         Ok(value)
304*9860b763SAndroid Build Coastguard Worker     } else {
305*9860b763SAndroid Build Coastguard Worker         Err(CborError::ExtraneousData)
306*9860b763SAndroid Build Coastguard Worker     }
307*9860b763SAndroid Build Coastguard Worker }
308*9860b763SAndroid Build Coastguard Worker 
309*9860b763SAndroid Build Coastguard Worker /// Trait for types that can be converted to/from a [`cbor::value::Value`].
310*9860b763SAndroid Build Coastguard Worker pub trait AsCborValue: Sized {
311*9860b763SAndroid Build Coastguard Worker     /// Convert a [`cbor::value::Value`] into an instance of the type.
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>312*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>;
313*9860b763SAndroid Build Coastguard Worker 
314*9860b763SAndroid Build Coastguard Worker     /// Convert the object into a [`cbor::value::Value`], consuming it along the way.
to_cbor_value(self) -> Result<cbor::value::Value, CborError>315*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError>;
316*9860b763SAndroid Build Coastguard Worker 
317*9860b763SAndroid Build Coastguard Worker     /// Create an object instance from serialized CBOR data in a slice.
from_slice(slice: &[u8]) -> Result<Self, CborError>318*9860b763SAndroid Build Coastguard Worker     fn from_slice(slice: &[u8]) -> Result<Self, CborError> {
319*9860b763SAndroid Build Coastguard Worker         Self::from_cbor_value(read_to_value(slice)?)
320*9860b763SAndroid Build Coastguard Worker     }
321*9860b763SAndroid Build Coastguard Worker 
322*9860b763SAndroid Build Coastguard Worker     /// Serialize this object to a vector, consuming it along the way.
into_vec(self) -> Result<Vec<u8>, CborError>323*9860b763SAndroid Build Coastguard Worker     fn into_vec(self) -> Result<Vec<u8>, CborError> {
324*9860b763SAndroid Build Coastguard Worker         let mut data = Vec::new();
325*9860b763SAndroid Build Coastguard Worker         cbor::ser::into_writer(&self.to_cbor_value()?, &mut data)?;
326*9860b763SAndroid Build Coastguard Worker         Ok(data)
327*9860b763SAndroid Build Coastguard Worker     }
328*9860b763SAndroid Build Coastguard Worker 
329*9860b763SAndroid Build Coastguard Worker     /// Return the name used for this type in a CDDL schema, or `None` if this type does not have a
330*9860b763SAndroid Build Coastguard Worker     /// simple CDDL name. (For example, type `Vec<i64>` maps to a schema `(+ int)` but doesn't
331*9860b763SAndroid Build Coastguard Worker     /// have a name.)
cddl_typename() -> Option<String>332*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
333*9860b763SAndroid Build Coastguard Worker         None
334*9860b763SAndroid Build Coastguard Worker     }
335*9860b763SAndroid Build Coastguard Worker 
336*9860b763SAndroid Build Coastguard Worker     /// Return the CDDL schema for this type, or None if this type is primitive (e.g. `int`, `bool`,
337*9860b763SAndroid Build Coastguard Worker     /// `bstr`).
cddl_schema() -> Option<String>338*9860b763SAndroid Build Coastguard Worker     fn cddl_schema() -> Option<String> {
339*9860b763SAndroid Build Coastguard Worker         None
340*9860b763SAndroid Build Coastguard Worker     }
341*9860b763SAndroid Build Coastguard Worker 
342*9860b763SAndroid Build Coastguard Worker     /// Return a way to refer to this type in CDDL; prefer the CDDL type name if available,
343*9860b763SAndroid Build Coastguard Worker     /// use the explicit schema if not.
cddl_ref() -> String344*9860b763SAndroid Build Coastguard Worker     fn cddl_ref() -> String {
345*9860b763SAndroid Build Coastguard Worker         if let Some(item_name) = Self::cddl_typename() {
346*9860b763SAndroid Build Coastguard Worker             item_name
347*9860b763SAndroid Build Coastguard Worker         } else if let Some(item_schema) = Self::cddl_schema() {
348*9860b763SAndroid Build Coastguard Worker             item_schema
349*9860b763SAndroid Build Coastguard Worker         } else {
350*9860b763SAndroid Build Coastguard Worker             panic!("type with unknown CDDL")
351*9860b763SAndroid Build Coastguard Worker         }
352*9860b763SAndroid Build Coastguard Worker     }
353*9860b763SAndroid Build Coastguard Worker }
354*9860b763SAndroid Build Coastguard Worker 
355*9860b763SAndroid Build Coastguard Worker // Implement the local `AsCborValue` trait for `coset::CoseEncrypt0` ensuring/requiring
356*9860b763SAndroid Build Coastguard Worker // use of the relevant CBOR tag.
357*9860b763SAndroid Build Coastguard Worker impl AsCborValue for coset::CoseEncrypt0 {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>358*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
359*9860b763SAndroid Build Coastguard Worker         match value {
360*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Tag(tag, inner_value) if tag == coset::CoseEncrypt0::TAG => {
361*9860b763SAndroid Build Coastguard Worker                 <coset::CoseEncrypt0 as coset::AsCborValue>::from_cbor_value(*inner_value)
362*9860b763SAndroid Build Coastguard Worker                     .map_err(|e| e.into())
363*9860b763SAndroid Build Coastguard Worker             }
364*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Tag(_, _) => Err(CborError::UnexpectedItem("tag", "tag 16")),
365*9860b763SAndroid Build Coastguard Worker             _ => cbor_type_error(&value, "tag 16"),
366*9860b763SAndroid Build Coastguard Worker         }
367*9860b763SAndroid Build Coastguard Worker     }
to_cbor_value(self) -> Result<cbor::value::Value, CborError>368*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
369*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Tag(
370*9860b763SAndroid Build Coastguard Worker             coset::CoseEncrypt0::TAG,
371*9860b763SAndroid Build Coastguard Worker             alloc::boxed::Box::new(coset::AsCborValue::to_cbor_value(self)?),
372*9860b763SAndroid Build Coastguard Worker         ))
373*9860b763SAndroid Build Coastguard Worker     }
cddl_schema() -> Option<String>374*9860b763SAndroid Build Coastguard Worker     fn cddl_schema() -> Option<String> {
375*9860b763SAndroid Build Coastguard Worker         Some(format!("#6.{}(Cose_Encrypt0)", coset::CoseEncrypt0::TAG))
376*9860b763SAndroid Build Coastguard Worker     }
377*9860b763SAndroid Build Coastguard Worker }
378*9860b763SAndroid Build Coastguard Worker 
379*9860b763SAndroid Build Coastguard Worker /// An `Option<T>` encodes as `( ? t )`, where `t` is whatever `T` encodes as in CDDL.
380*9860b763SAndroid Build Coastguard Worker impl<T: AsCborValue> AsCborValue for Option<T> {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>381*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
382*9860b763SAndroid Build Coastguard Worker         let mut arr = match value {
383*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Array(a) => a,
384*9860b763SAndroid Build Coastguard Worker             _ => return Err(CborError::UnexpectedItem("non-arr", "arr")),
385*9860b763SAndroid Build Coastguard Worker         };
386*9860b763SAndroid Build Coastguard Worker         match arr.len() {
387*9860b763SAndroid Build Coastguard Worker             0 => Ok(None),
388*9860b763SAndroid Build Coastguard Worker             1 => Ok(Some(<T>::from_cbor_value(arr.remove(0))?)),
389*9860b763SAndroid Build Coastguard Worker             _ => Err(CborError::UnexpectedItem("arr len >1", "arr len 0/1")),
390*9860b763SAndroid Build Coastguard Worker         }
391*9860b763SAndroid Build Coastguard Worker     }
392*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>393*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
394*9860b763SAndroid Build Coastguard Worker         match self {
395*9860b763SAndroid Build Coastguard Worker             Some(t) => Ok(cbor::value::Value::Array(vec_try![t.to_cbor_value()?]?)),
396*9860b763SAndroid Build Coastguard Worker             None => Ok(cbor::value::Value::Array(Vec::new())),
397*9860b763SAndroid Build Coastguard Worker         }
398*9860b763SAndroid Build Coastguard Worker     }
399*9860b763SAndroid Build Coastguard Worker 
cddl_schema() -> Option<String>400*9860b763SAndroid Build Coastguard Worker     fn cddl_schema() -> Option<String> {
401*9860b763SAndroid Build Coastguard Worker         Some(format!("[? {}]", <T>::cddl_ref()))
402*9860b763SAndroid Build Coastguard Worker     }
403*9860b763SAndroid Build Coastguard Worker }
404*9860b763SAndroid Build Coastguard Worker 
405*9860b763SAndroid Build Coastguard Worker /// A `Vec<T>` encodes as `( * t )`, where `t` is whatever `T` encodes as in CDDL.
406*9860b763SAndroid Build Coastguard Worker impl<T: AsCborValue> AsCborValue for Vec<T> {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>407*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
408*9860b763SAndroid Build Coastguard Worker         let arr = match value {
409*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Array(a) => a,
410*9860b763SAndroid Build Coastguard Worker             _ => return cbor_type_error(&value, "arr"),
411*9860b763SAndroid Build Coastguard Worker         };
412*9860b763SAndroid Build Coastguard Worker         let results: Result<Vec<_>, _> = arr.into_iter().map(<T>::from_cbor_value).collect();
413*9860b763SAndroid Build Coastguard Worker         results
414*9860b763SAndroid Build Coastguard Worker     }
415*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>416*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
417*9860b763SAndroid Build Coastguard Worker         let values: Result<Vec<_>, _> = self.into_iter().map(|v| v.to_cbor_value()).collect();
418*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Array(values?))
419*9860b763SAndroid Build Coastguard Worker     }
420*9860b763SAndroid Build Coastguard Worker 
cddl_schema() -> Option<String>421*9860b763SAndroid Build Coastguard Worker     fn cddl_schema() -> Option<String> {
422*9860b763SAndroid Build Coastguard Worker         Some(format!("[* {}]", <T>::cddl_ref()))
423*9860b763SAndroid Build Coastguard Worker     }
424*9860b763SAndroid Build Coastguard Worker }
425*9860b763SAndroid Build Coastguard Worker 
426*9860b763SAndroid Build Coastguard Worker impl AsCborValue for Vec<u8> {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>427*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
428*9860b763SAndroid Build Coastguard Worker         match value {
429*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Bytes(bstr) => Ok(bstr),
430*9860b763SAndroid Build Coastguard Worker             _ => cbor_type_error(&value, "bstr"),
431*9860b763SAndroid Build Coastguard Worker         }
432*9860b763SAndroid Build Coastguard Worker     }
433*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>434*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
435*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Bytes(self))
436*9860b763SAndroid Build Coastguard Worker     }
437*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>438*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
439*9860b763SAndroid Build Coastguard Worker         Some("bstr".to_string())
440*9860b763SAndroid Build Coastguard Worker     }
441*9860b763SAndroid Build Coastguard Worker }
442*9860b763SAndroid Build Coastguard Worker 
443*9860b763SAndroid Build Coastguard Worker impl<const N: usize> AsCborValue for [u8; N] {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>444*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
445*9860b763SAndroid Build Coastguard Worker         let data = match value {
446*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Bytes(bstr) => bstr,
447*9860b763SAndroid Build Coastguard Worker             _ => return cbor_type_error(&value, "bstr"),
448*9860b763SAndroid Build Coastguard Worker         };
449*9860b763SAndroid Build Coastguard Worker         data.try_into()
450*9860b763SAndroid Build Coastguard Worker             .map_err(|_e| CborError::UnexpectedItem("bstr other size", "bstr specific size"))
451*9860b763SAndroid Build Coastguard Worker     }
452*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>453*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
454*9860b763SAndroid Build Coastguard Worker         let mut v = alloc::vec::Vec::new();
455*9860b763SAndroid Build Coastguard Worker         if v.try_reserve(self.len()).is_err() {
456*9860b763SAndroid Build Coastguard Worker             return Err(CborError::AllocationFailed);
457*9860b763SAndroid Build Coastguard Worker         }
458*9860b763SAndroid Build Coastguard Worker         v.extend_from_slice(&self);
459*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Bytes(v))
460*9860b763SAndroid Build Coastguard Worker     }
461*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>462*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
463*9860b763SAndroid Build Coastguard Worker         Some(format!("bstr .size {}", N))
464*9860b763SAndroid Build Coastguard Worker     }
465*9860b763SAndroid Build Coastguard Worker }
466*9860b763SAndroid Build Coastguard Worker 
467*9860b763SAndroid Build Coastguard Worker impl AsCborValue for String {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>468*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
469*9860b763SAndroid Build Coastguard Worker         match value {
470*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Text(s) => Ok(s),
471*9860b763SAndroid Build Coastguard Worker             _ => cbor_type_error(&value, "tstr"),
472*9860b763SAndroid Build Coastguard Worker         }
473*9860b763SAndroid Build Coastguard Worker     }
474*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>475*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
476*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Text(self))
477*9860b763SAndroid Build Coastguard Worker     }
478*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>479*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
480*9860b763SAndroid Build Coastguard Worker         Some("tstr".to_string())
481*9860b763SAndroid Build Coastguard Worker     }
482*9860b763SAndroid Build Coastguard Worker }
483*9860b763SAndroid Build Coastguard Worker 
484*9860b763SAndroid Build Coastguard Worker impl AsCborValue for u64 {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>485*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
486*9860b763SAndroid Build Coastguard Worker         match value {
487*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Integer(i) => {
488*9860b763SAndroid Build Coastguard Worker                 i.try_into().map_err(|_| crate::CborError::OutOfRangeIntegerValue)
489*9860b763SAndroid Build Coastguard Worker             }
490*9860b763SAndroid Build Coastguard Worker             v => crate::cbor_type_error(&v, "u64"),
491*9860b763SAndroid Build Coastguard Worker         }
492*9860b763SAndroid Build Coastguard Worker     }
493*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>494*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
495*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Integer(self.into()))
496*9860b763SAndroid Build Coastguard Worker     }
497*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>498*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
499*9860b763SAndroid Build Coastguard Worker         Some("int".to_string())
500*9860b763SAndroid Build Coastguard Worker     }
501*9860b763SAndroid Build Coastguard Worker }
502*9860b763SAndroid Build Coastguard Worker 
503*9860b763SAndroid Build Coastguard Worker impl AsCborValue for i64 {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>504*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
505*9860b763SAndroid Build Coastguard Worker         match value {
506*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Integer(i) => {
507*9860b763SAndroid Build Coastguard Worker                 i.try_into().map_err(|_| crate::CborError::OutOfRangeIntegerValue)
508*9860b763SAndroid Build Coastguard Worker             }
509*9860b763SAndroid Build Coastguard Worker             v => crate::cbor_type_error(&v, "i64"),
510*9860b763SAndroid Build Coastguard Worker         }
511*9860b763SAndroid Build Coastguard Worker     }
512*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>513*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
514*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Integer(self.into()))
515*9860b763SAndroid Build Coastguard Worker     }
516*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>517*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
518*9860b763SAndroid Build Coastguard Worker         Some("int".to_string())
519*9860b763SAndroid Build Coastguard Worker     }
520*9860b763SAndroid Build Coastguard Worker }
521*9860b763SAndroid Build Coastguard Worker 
522*9860b763SAndroid Build Coastguard Worker impl AsCborValue for u32 {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>523*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
524*9860b763SAndroid Build Coastguard Worker         match value {
525*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Integer(i) => {
526*9860b763SAndroid Build Coastguard Worker                 i.try_into().map_err(|_| crate::CborError::OutOfRangeIntegerValue)
527*9860b763SAndroid Build Coastguard Worker             }
528*9860b763SAndroid Build Coastguard Worker             v => crate::cbor_type_error(&v, "u32"),
529*9860b763SAndroid Build Coastguard Worker         }
530*9860b763SAndroid Build Coastguard Worker     }
531*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>532*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
533*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Integer(self.into()))
534*9860b763SAndroid Build Coastguard Worker     }
535*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>536*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
537*9860b763SAndroid Build Coastguard Worker         Some("int".to_string())
538*9860b763SAndroid Build Coastguard Worker     }
539*9860b763SAndroid Build Coastguard Worker }
540*9860b763SAndroid Build Coastguard Worker 
541*9860b763SAndroid Build Coastguard Worker impl AsCborValue for bool {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>542*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
543*9860b763SAndroid Build Coastguard Worker         match value {
544*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Bool(b) => Ok(b),
545*9860b763SAndroid Build Coastguard Worker             v => crate::cbor_type_error(&v, "bool"),
546*9860b763SAndroid Build Coastguard Worker         }
547*9860b763SAndroid Build Coastguard Worker     }
to_cbor_value(self) -> Result<cbor::value::Value, CborError>548*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
549*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Bool(self))
550*9860b763SAndroid Build Coastguard Worker     }
551*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>552*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
553*9860b763SAndroid Build Coastguard Worker         Some("bool".to_string())
554*9860b763SAndroid Build Coastguard Worker     }
555*9860b763SAndroid Build Coastguard Worker }
556*9860b763SAndroid Build Coastguard Worker 
557*9860b763SAndroid Build Coastguard Worker impl AsCborValue for () {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>558*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
559*9860b763SAndroid Build Coastguard Worker         match value {
560*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Null => Ok(()),
561*9860b763SAndroid Build Coastguard Worker             v => crate::cbor_type_error(&v, "null"),
562*9860b763SAndroid Build Coastguard Worker         }
563*9860b763SAndroid Build Coastguard Worker     }
to_cbor_value(self) -> Result<cbor::value::Value, CborError>564*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
565*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Null)
566*9860b763SAndroid Build Coastguard Worker     }
567*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>568*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
569*9860b763SAndroid Build Coastguard Worker         Some("null".to_string())
570*9860b763SAndroid Build Coastguard Worker     }
571*9860b763SAndroid Build Coastguard Worker }
572*9860b763SAndroid Build Coastguard Worker 
573*9860b763SAndroid Build Coastguard Worker impl AsCborValue for i32 {
from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError>574*9860b763SAndroid Build Coastguard Worker     fn from_cbor_value(value: cbor::value::Value) -> Result<Self, CborError> {
575*9860b763SAndroid Build Coastguard Worker         match value {
576*9860b763SAndroid Build Coastguard Worker             cbor::value::Value::Integer(i) => {
577*9860b763SAndroid Build Coastguard Worker                 i.try_into().map_err(|_| crate::CborError::OutOfRangeIntegerValue)
578*9860b763SAndroid Build Coastguard Worker             }
579*9860b763SAndroid Build Coastguard Worker             v => crate::cbor_type_error(&v, "i64"),
580*9860b763SAndroid Build Coastguard Worker         }
581*9860b763SAndroid Build Coastguard Worker     }
582*9860b763SAndroid Build Coastguard Worker 
to_cbor_value(self) -> Result<cbor::value::Value, CborError>583*9860b763SAndroid Build Coastguard Worker     fn to_cbor_value(self) -> Result<cbor::value::Value, CborError> {
584*9860b763SAndroid Build Coastguard Worker         Ok(cbor::value::Value::Integer(self.into()))
585*9860b763SAndroid Build Coastguard Worker     }
586*9860b763SAndroid Build Coastguard Worker 
cddl_typename() -> Option<String>587*9860b763SAndroid Build Coastguard Worker     fn cddl_typename() -> Option<String> {
588*9860b763SAndroid Build Coastguard Worker         Some("int".to_string())
589*9860b763SAndroid Build Coastguard Worker     }
590*9860b763SAndroid Build Coastguard Worker }
591