use crate::cose_keys::Curve;
use minicbor::{
Decode, Decoder, Encode, bytes::EncodeBytes, data::Type, decode::Error as DecodeError,
};
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
#[cfg_attr(test, derive(PartialEq))]
pub enum BytesBool<'a> {
Bytes(&'a [u8]),
Bool(bool),
}
impl<'a, C> Encode<C> for BytesBool<'a> {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
match self {
BytesBool::Bool(b) => b.encode(e, ctx),
BytesBool::Bytes(bytes) => bytes.encode_bytes(e, ctx),
}
}
}
impl<'a, Ctx> Decode<'a, Ctx> for BytesBool<'a> {
fn decode(d: &mut Decoder<'a>, ctx: &mut Ctx) -> Result<Self, DecodeError> {
let ty = d.datatype()?;
match ty {
Type::Bytes => Ok(BytesBool::Bytes(minicbor::bytes::decode(d, ctx)?)),
Type::Bool => Ok(BytesBool::Bool(bool::decode(d, ctx)?)),
_ => Err(DecodeError::type_mismatch(ty).with_message("expected integer op id")),
}
}
}
impl<'a> From<&'a [u8]> for BytesBool<'a> {
fn from(bytes: &'a [u8]) -> Self {
BytesBool::Bytes(bytes)
}
}
impl From<bool> for BytesBool<'_> {
fn from(b: bool) -> Self {
BytesBool::Bool(b)
}
}
impl<'a, const N: usize> From<&'a [u8; N]> for BytesBool<'a> {
fn from(bytes: &'a [u8; N]) -> Self {
BytesBool::Bytes(bytes)
}
}
#[derive(Debug, Clone, Copy)]
#[cfg_attr(test, derive(PartialEq))]
pub(crate) enum CrvOrK<'a> {
Crv(Curve),
K(&'a [u8]),
}
impl<'a, C> Encode<C> for CrvOrK<'a> {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
match self {
CrvOrK::Crv(crv_id) => crv_id.encode(e, ctx),
CrvOrK::K(bytes) => bytes.encode_bytes(e, ctx),
}
}
}
impl<'a, Ctx> Decode<'a, Ctx> for CrvOrK<'a> {
fn decode(d: &mut Decoder<'a>, ctx: &mut Ctx) -> Result<Self, DecodeError> {
let ty = d.datatype()?;
match ty {
Type::Bytes => Ok(CrvOrK::K(minicbor::bytes::decode(d, ctx)?)),
Type::String | Type::U8 => Ok(CrvOrK::Crv(Curve::decode(d, ctx)?)),
_ => Err(DecodeError::type_mismatch(ty).with_message("expected integer op id")),
}
}
}
#[derive(Debug, Encode)]
#[allow(dead_code)]
pub(crate) enum TstrOrInt<'a> {
#[n(0)]
Int(#[n(0)] i32),
#[n(1)]
Tstr(#[n(0)] &'a str),
}
impl<'a, Ctx> Decode<'a, Ctx> for TstrOrInt<'a> {
fn decode(d: &mut Decoder<'a>, _ctx: &mut Ctx) -> Result<Self, DecodeError> {
let ty = d.datatype()?;
match ty {
Type::String => Ok(TstrOrInt::Tstr(
str::from_utf8(d.bytes()?)
.map_err(|_e| DecodeError::message("Utf8 parsing error for TstrOrInt"))?,
)),
Type::I32 => Ok(TstrOrInt::Int(i32::decode(d, _ctx)?)),
_ => Err(minicbor::decode::Error::message(
"unexpected type for SuitAuthenticationBlock",
)),
}
}
}
#[allow(dead_code)]
pub(crate) enum NulOrBytes<'a> {
Nul,
#[allow(dead_code)]
Bytes(&'a [u8]),
}
impl<C> Encode<C> for NulOrBytes<'_> {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
match self {
NulOrBytes::Bytes(bytes) => bytes.encode_bytes(e, ctx),
NulOrBytes::Nul => {
e.null()?;
Ok(())
}
}
}
}