s/read_cbor_map/destructure_cbor_map/g
This commit is contained in:
@@ -24,16 +24,16 @@ use core::iter::Peekable;
|
|||||||
/// that assigns the corresponding values to new variables using the given identifiers. Each of
|
/// that assigns the corresponding values to new variables using the given identifiers. Each of
|
||||||
/// these variables has type `Option<Value>`, to account for the case where keys aren't found.
|
/// these variables has type `Option<Value>`, to account for the case where keys aren't found.
|
||||||
///
|
///
|
||||||
/// **Important:** Keys passed to the `read_cbor_map!` macro **must be sorted** in increasing order.
|
/// **Important:** Keys passed to the `destructure_cbor_map!` macro **must be sorted** in increasing
|
||||||
/// If not, the algorithm can yield incorrect results, such a assigning `None` to a variable even if
|
/// order. If not, the algorithm can yield incorrect results, such a assigning `None` to a variable
|
||||||
/// the corresponding key existed in the map. **No runtime checks** are made for this in the
|
/// even if the corresponding key existed in the map. **No runtime checks** are made for this in the
|
||||||
/// `read_cbor_map!` macro, in order to avoid overhead at runtime. However, assertions that keys are
|
/// `destructure_cbor_map!` macro, in order to avoid overhead at runtime. However, assertions that
|
||||||
/// sorted are added in `cfg(test)` mode, so that unit tests can verify ahead of time that the keys
|
/// keys are sorted are added in `cfg(test)` mode, so that unit tests can verify ahead of time that
|
||||||
/// are indeed sorted. This macro is therefore **not suitable for dynamic keys** that can change at
|
/// the keys are indeed sorted. This macro is therefore **not suitable for dynamic keys** that can
|
||||||
/// runtime.
|
/// change at runtime.
|
||||||
///
|
///
|
||||||
/// Semantically, provided that the keys are sorted as specified above, the following two snippets
|
/// Semantically, provided that the keys are sorted as specified above, the following two snippets
|
||||||
/// of code are equivalent, but the `read_cbor_map!` version is more optimized, as it doesn't
|
/// of code are equivalent, but the `destructure_cbor_map!` version is more optimized, as it doesn't
|
||||||
/// re-balance the `BTreeMap` for each key, contrary to the `BTreeMap::remove` operations.
|
/// re-balance the `BTreeMap` for each key, contrary to the `BTreeMap::remove` operations.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
@@ -43,7 +43,7 @@ use core::iter::Peekable;
|
|||||||
/// #
|
/// #
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// # let map = alloc::collections::BTreeMap::new();
|
/// # let map = alloc::collections::BTreeMap::new();
|
||||||
/// read_cbor_map! {
|
/// destructure_cbor_map! {
|
||||||
/// let {
|
/// let {
|
||||||
/// 1 => x,
|
/// 1 => x,
|
||||||
/// "key" => y,
|
/// "key" => y,
|
||||||
@@ -65,7 +65,7 @@ use core::iter::Peekable;
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! read_cbor_map {
|
macro_rules! destructure_cbor_map {
|
||||||
( let { $( $key:expr => $variable:ident, )+ } = $map:expr; ) => {
|
( let { $( $key:expr => $variable:ident, )+ } = $map:expr; ) => {
|
||||||
// A pre-requisite for this algorithm to work is that the keys to extract from the map are
|
// A pre-requisite for this algorithm to work is that the keys to extract from the map are
|
||||||
// sorted.
|
// sorted.
|
||||||
@@ -73,22 +73,22 @@ macro_rules! read_cbor_map {
|
|||||||
test_ordered_keys!($( $key, )+);
|
test_ordered_keys!($( $key, )+);
|
||||||
|
|
||||||
use $crate::values::{IntoCborKey, Value};
|
use $crate::values::{IntoCborKey, Value};
|
||||||
use $crate::macros::read_cbor_map_peek_value;
|
use $crate::macros::destructure_cbor_map_peek_value;
|
||||||
|
|
||||||
let mut it = $map.into_iter().peekable();
|
let mut it = $map.into_iter().peekable();
|
||||||
$(
|
$(
|
||||||
let $variable: Option<Value> = read_cbor_map_peek_value(&mut it, $key.into_cbor_key());
|
let $variable: Option<Value> = destructure_cbor_map_peek_value(&mut it, $key.into_cbor_key());
|
||||||
)+
|
)+
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is an internal detail of the `read_cbor_map!` macro, but has public visibility so
|
/// This function is an internal detail of the `destructure_cbor_map!` macro, but has public
|
||||||
/// that users of the macro can use it.
|
/// visibility so that users of the macro can use it.
|
||||||
///
|
///
|
||||||
/// The logic is separated into its own function to reduce binary size, as otherwise the logic
|
/// The logic is separated into its own function to reduce binary size, as otherwise the logic
|
||||||
/// would be inlined for every use case. As of June 2020, this saves ~40KB of binary size for the
|
/// would be inlined for every use case. As of June 2020, this saves ~40KB of binary size for the
|
||||||
/// CTAP2 application of OpenSK.
|
/// CTAP2 application of OpenSK.
|
||||||
pub fn read_cbor_map_peek_value(
|
pub fn destructure_cbor_map_peek_value(
|
||||||
it: &mut Peekable<btree_map::IntoIter<KeyType, Value>>,
|
it: &mut Peekable<btree_map::IntoIter<KeyType, Value>>,
|
||||||
needle: KeyType,
|
needle: KeyType,
|
||||||
) -> Option<Value> {
|
) -> Option<Value> {
|
||||||
@@ -125,7 +125,7 @@ macro_rules! test_ordered_keys {
|
|||||||
let k2: KeyType = $key2.into_cbor_key();
|
let k2: KeyType = $key2.into_cbor_key();
|
||||||
assert!(
|
assert!(
|
||||||
k1 < k2,
|
k1 < k2,
|
||||||
"{:?} < {:?} failed. The read_cbor_map! macro requires keys in sorted order.",
|
"{:?} < {:?} failed. The destructure_cbor_map! macro requires keys in sorted order.",
|
||||||
k1,
|
k1,
|
||||||
k2,
|
k2,
|
||||||
);
|
);
|
||||||
@@ -628,13 +628,13 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_read_cbor_map_simple() {
|
fn test_destructure_cbor_map_simple() {
|
||||||
let map = cbor_map! {
|
let map = cbor_map! {
|
||||||
1 => 10,
|
1 => 10,
|
||||||
2 => 20,
|
2 => 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
1 => x1,
|
1 => x1,
|
||||||
2 => x2,
|
2 => x2,
|
||||||
@@ -647,13 +647,13 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_read_cbor_map_unordered() {
|
fn test_destructure_cbor_map_unordered() {
|
||||||
let map = cbor_map! {
|
let map = cbor_map! {
|
||||||
1 => 10,
|
1 => 10,
|
||||||
2 => 20,
|
2 => 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
2 => _x2,
|
2 => _x2,
|
||||||
1 => _x1,
|
1 => _x1,
|
||||||
@@ -662,7 +662,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_read_cbor_map_partial() {
|
fn test_destructure_cbor_map_partial() {
|
||||||
let map = cbor_map! {
|
let map = cbor_map! {
|
||||||
1 => 10,
|
1 => 10,
|
||||||
2 => 20,
|
2 => 20,
|
||||||
@@ -675,7 +675,7 @@ mod test {
|
|||||||
9 => 90,
|
9 => 90,
|
||||||
};
|
};
|
||||||
|
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
3 => x3,
|
3 => x3,
|
||||||
7 => x7,
|
7 => x7,
|
||||||
@@ -687,14 +687,14 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_read_cbor_map_missing() {
|
fn test_destructure_cbor_map_missing() {
|
||||||
let map = cbor_map! {
|
let map = cbor_map! {
|
||||||
1 => 10,
|
1 => 10,
|
||||||
3 => 30,
|
3 => 30,
|
||||||
4 => 40,
|
4 => 40,
|
||||||
};
|
};
|
||||||
|
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
0 => x0,
|
0 => x0,
|
||||||
1 => x1,
|
1 => x1,
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ impl TryFrom<cbor::Value> for AuthenticatorMakeCredentialParameters {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
1 => client_data_hash,
|
1 => client_data_hash,
|
||||||
2 => rp,
|
2 => rp,
|
||||||
@@ -207,7 +207,7 @@ impl TryFrom<cbor::Value> for AuthenticatorGetAssertionParameters {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
1 => rp_id,
|
1 => rp_id,
|
||||||
2 => client_data_hash,
|
2 => client_data_hash,
|
||||||
@@ -277,7 +277,7 @@ impl TryFrom<cbor::Value> for AuthenticatorClientPinParameters {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
1 => pin_protocol,
|
1 => pin_protocol,
|
||||||
2 => sub_command,
|
2 => sub_command,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialRpEntity {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"id" => rp_id,
|
"id" => rp_id,
|
||||||
"icon" => rp_icon,
|
"icon" => rp_icon,
|
||||||
@@ -64,7 +64,7 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialUserEntity {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"id" => user_id,
|
"id" => user_id,
|
||||||
"icon" => user_icon,
|
"icon" => user_icon,
|
||||||
@@ -143,7 +143,7 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialParameter {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"alg" => alg,
|
"alg" => alg,
|
||||||
"type" => cred_type,
|
"type" => cred_type,
|
||||||
@@ -213,7 +213,7 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialDescriptor {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"id" => key_id,
|
"id" => key_id,
|
||||||
"type" => key_type,
|
"type" => key_type,
|
||||||
@@ -263,7 +263,7 @@ impl TryFrom<cbor::Value> for MakeCredentialExtensions {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"credProtect" => cred_protect,
|
"credProtect" => cred_protect,
|
||||||
"hmac-secret" => hmac_secret,
|
"hmac-secret" => hmac_secret,
|
||||||
@@ -290,7 +290,7 @@ impl TryFrom<cbor::Value> for GetAssertionExtensions {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"hmac-secret" => hmac_secret,
|
"hmac-secret" => hmac_secret,
|
||||||
} = extract_map(cbor_value)?;
|
} = extract_map(cbor_value)?;
|
||||||
@@ -314,7 +314,7 @@ impl TryFrom<cbor::Value> for GetAssertionHmacSecretInput {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
1 => cose_key,
|
1 => cose_key,
|
||||||
2 => salt_enc,
|
2 => salt_enc,
|
||||||
@@ -344,7 +344,7 @@ impl TryFrom<cbor::Value> for MakeCredentialOptions {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"rk" => rk,
|
"rk" => rk,
|
||||||
"up" => up,
|
"up" => up,
|
||||||
@@ -379,7 +379,7 @@ impl TryFrom<cbor::Value> for GetAssertionOptions {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
"rk" => rk,
|
"rk" => rk,
|
||||||
"up" => up,
|
"up" => up,
|
||||||
@@ -542,7 +542,7 @@ impl TryFrom<cbor::Value> for PublicKeyCredentialSource {
|
|||||||
use PublicKeyCredentialSourceField::{
|
use PublicKeyCredentialSourceField::{
|
||||||
CredProtectPolicy, CredRandom, CredentialId, OtherUi, PrivateKey, RpId, UserHandle,
|
CredProtectPolicy, CredRandom, CredentialId, OtherUi, PrivateKey, RpId, UserHandle,
|
||||||
};
|
};
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
CredentialId => credential_id,
|
CredentialId => credential_id,
|
||||||
PrivateKey => private_key,
|
PrivateKey => private_key,
|
||||||
@@ -643,7 +643,7 @@ impl TryFrom<CoseKey> for ecdh::PubKey {
|
|||||||
type Error = Ctap2StatusCode;
|
type Error = Ctap2StatusCode;
|
||||||
|
|
||||||
fn try_from(cose_key: CoseKey) -> Result<Self, Ctap2StatusCode> {
|
fn try_from(cose_key: CoseKey) -> Result<Self, Ctap2StatusCode> {
|
||||||
read_cbor_map! {
|
destructure_cbor_map! {
|
||||||
let {
|
let {
|
||||||
1 => key_type,
|
1 => key_type,
|
||||||
3 => algorithm,
|
3 => algorithm,
|
||||||
|
|||||||
Reference in New Issue
Block a user