use minicbor::{data::Tag, Decode, Encode}; use serde::{Deserialize, Serialize}; use std::ops::Deref; /// Utility for skipping parts of the CBOR payload, use only for debugging #[derive(Debug, PartialEq, PartialOrd, Eq, Ord)] pub struct SkipCbor {} impl<'b, C, const N: usize> minicbor::Decode<'b, C> for SkipCbor { fn decode( d: &mut minicbor::Decoder<'b>, _ctx: &mut C, ) -> Result { { let probe = d.probe(); println!("skipped cbor value {}: {:?}", N, probe.datatype()?); } d.skip()?; Ok(SkipCbor {}) } } impl minicbor::Encode for SkipCbor { fn encode( &self, _e: &mut minicbor::Encoder, _ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { todo!() } } /// Custom collection to ensure ordered pairs of values /// /// Since the ordering of the entries requires a particular order to maintain /// canonicalization for isomorphic decoding / encoding operators, we use a Vec /// as the underlaying struct for storage of the items (as opposed to a BTreeMap /// or HashMap). #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] #[serde(from = "Vec::<(K, V)>", into = "Vec::<(K, V)>")] pub enum KeyValuePairs where K: Clone, V: Clone, { Def(Vec<(K, V)>), Indef(Vec<(K, V)>), } impl KeyValuePairs where K: Clone, V: Clone, { pub fn to_vec(self) -> Vec<(K, V)> { self.into() } } impl From> for Vec<(K, V)> where K: Clone, V: Clone, { fn from(other: KeyValuePairs) -> Self { match other { KeyValuePairs::Def(x) => x, KeyValuePairs::Indef(x) => x, } } } impl From> for KeyValuePairs where K: Clone, V: Clone, { fn from(other: Vec<(K, V)>) -> Self { KeyValuePairs::Def(other) } } impl Deref for KeyValuePairs where K: Clone, V: Clone, { type Target = Vec<(K, V)>; fn deref(&self) -> &Self::Target { match self { KeyValuePairs::Def(x) => x, KeyValuePairs::Indef(x) => x, } } } impl<'b, C, K, V> minicbor::decode::Decode<'b, C> for KeyValuePairs where K: Encode + Decode<'b, C> + Clone, V: Encode + Decode<'b, C> + Clone, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { let datatype = d.datatype()?; let items: Result, _> = d.map_iter_with::(ctx)?.collect(); let items = items?; match datatype { minicbor::data::Type::Map => Ok(KeyValuePairs::Def(items)), minicbor::data::Type::MapIndef => Ok(KeyValuePairs::Indef(items)), _ => Err(minicbor::decode::Error::message( "invalid data type for keyvaluepairs", )), } } } impl minicbor::encode::Encode for KeyValuePairs where K: Encode + Clone, V: Encode + Clone, { fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { match self { KeyValuePairs::Def(x) => { e.map(x.len() as u64)?; for (k, v) in x.iter() { k.encode(e, ctx)?; v.encode(e, ctx)?; } } KeyValuePairs::Indef(x) => { e.begin_map()?; for (k, v) in x.iter() { k.encode(e, ctx)?; v.encode(e, ctx)?; } e.end()?; } } Ok(()) } } /// A struct that maintains a reference to whether a cbor array was indef or not #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub enum MaybeIndefArray { Def(Vec), Indef(Vec), } impl MaybeIndefArray { pub fn to_vec(self) -> Vec { self.into() } } impl Deref for MaybeIndefArray { type Target = Vec; fn deref(&self) -> &Self::Target { match self { MaybeIndefArray::Def(x) => x, MaybeIndefArray::Indef(x) => x, } } } impl From> for Vec { fn from(other: MaybeIndefArray) -> Self { match other { MaybeIndefArray::Def(x) => x, MaybeIndefArray::Indef(x) => x, } } } impl<'b, C, A> minicbor::decode::Decode<'b, C> for MaybeIndefArray where A: minicbor::decode::Decode<'b, C>, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { let datatype = d.datatype()?; match datatype { minicbor::data::Type::Array => Ok(Self::Def(d.decode_with(ctx)?)), minicbor::data::Type::ArrayIndef => Ok(Self::Indef(d.decode_with(ctx)?)), _ => Err(minicbor::decode::Error::message( "unknown data type of maybe indef array", )), } } } impl minicbor::encode::Encode for MaybeIndefArray where A: minicbor::encode::Encode, { fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { match self { MaybeIndefArray::Def(x) => { e.encode_with(x, ctx)?; } // TODO: this seemed necesary on alonzo, but breaks on byron. We need to double check. //MaybeIndefArray::Indef(x) if x.is_empty() => { // e.encode(x)?; //} MaybeIndefArray::Indef(x) => { e.begin_array()?; for v in x.iter() { e.encode_with(v, ctx)?; } e.end()?; } }; Ok(()) } } /// Order-preserving set of attributes /// /// There's no guarantee that the entries on a Cardano cbor entity that uses /// maps for its representation will follow the canonical order specified by the /// standard. To implement an isomorphic codec, we need a way of preserving the /// original order in which the entries were encoded. To acomplish this, we /// transform key-value structures into an orderer vec of `properties`, where /// each entry represents a a cbor-encodable variant of an attribute of the /// struct. #[derive(Debug, PartialEq, Eq, Clone, PartialOrd)] pub struct OrderPreservingProperties

(Vec

); impl

Deref for OrderPreservingProperties

{ type Target = Vec

; fn deref(&self) -> &Self::Target { &self.0 } } impl<'b, C, P> minicbor::decode::Decode<'b, C> for OrderPreservingProperties

where P: Decode<'b, C>, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { let len = d.map()?.unwrap_or_default(); let components: Result<_, _> = (0..len).map(|_| d.decode_with(ctx)).collect(); Ok(Self(components?)) } } impl minicbor::encode::Encode for OrderPreservingProperties

where P: Encode, { fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { e.map(self.0.len() as u64)?; for component in &self.0 { e.encode_with(component, ctx)?; } Ok(()) } } /// Wraps a struct so that it is encoded/decoded as a cbor bytes #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd)] #[serde(transparent)] pub struct CborWrap(pub T); impl<'b, C, T> minicbor::Decode<'b, C> for CborWrap where T: minicbor::Decode<'b, C>, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { d.tag()?; let cbor = d.bytes()?; let wrapped = minicbor::decode_with(cbor, ctx)?; Ok(CborWrap(wrapped)) } } impl minicbor::Encode for CborWrap where T: minicbor::Encode, { fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { let buf = minicbor::to_vec_with(&self.0, ctx).map_err(|_| { minicbor::encode::Error::message("error encoding cbor-wrapped structure") })?; e.tag(Tag::Cbor)?; e.bytes(&buf)?; Ok(()) } } impl Deref for CborWrap { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct TagWrap(pub I); impl TagWrap { pub fn new(inner: I) -> Self { TagWrap(inner) } } impl<'b, C, I, const T: u64> minicbor::Decode<'b, C> for TagWrap where I: minicbor::Decode<'b, C>, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { d.tag()?; Ok(TagWrap(d.decode_with(ctx)?)) } } impl minicbor::Encode for TagWrap where I: minicbor::Encode, { fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { e.tag(Tag::Unassigned(T))?; e.encode_with(&self.0, ctx)?; Ok(()) } } impl Deref for TagWrap { type Target = I; fn deref(&self) -> &Self::Target { &self.0 } } /// An empty map /// /// don't ask me why, that's what the CDDL asks for. #[derive(Debug, Clone)] pub struct EmptyMap; impl<'b, C> minicbor::decode::Decode<'b, C> for EmptyMap { fn decode( d: &mut minicbor::Decoder<'b>, _ctx: &mut C, ) -> Result { d.skip()?; Ok(EmptyMap) } } impl minicbor::encode::Encode for EmptyMap { fn encode( &self, e: &mut minicbor::Encoder, _ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { e.map(0)?; Ok(()) } } /// An array with zero or one elements /// /// A common pattern seen in the CDDL is to represent optional values as an /// array containing zero or more items. This structure reflects that pattern /// while providing semantic meaning. #[derive(Debug, Clone)] pub struct ZeroOrOneArray(Option); impl Deref for ZeroOrOneArray { type Target = Option; fn deref(&self) -> &Self::Target { &self.0 } } impl<'b, C, T> minicbor::decode::Decode<'b, C> for ZeroOrOneArray where T: Decode<'b, C>, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { let len = d.array()?; match len { Some(0) => Ok(ZeroOrOneArray(None)), Some(1) => Ok(ZeroOrOneArray(Some(d.decode_with(ctx)?))), Some(_) => Err(minicbor::decode::Error::message( "found invalid len for zero-or-one pattern", )), None => Err(minicbor::decode::Error::message( "found invalid indefinite len array for zero-or-one pattern", )), } } } impl minicbor::encode::Encode for ZeroOrOneArray where T: minicbor::Encode, { fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { match &self.0 { Some(x) => { e.array(1)?; e.encode_with(x, ctx)?; } None => { e.array(0)?; } } Ok(()) } } /// A uint structure that preserves original int length #[derive(Debug, PartialEq, Copy, Clone, PartialOrd, Eq, Ord)] pub enum AnyUInt { MajorByte(u8), U8(u8), U16(u16), U32(u32), U64(u64), } impl<'b, C> minicbor::decode::Decode<'b, C> for AnyUInt { fn decode( d: &mut minicbor::Decoder<'b>, _ctx: &mut C, ) -> Result { match d.datatype()? { minicbor::data::Type::U8 => match d.u8()? { x @ 0..=0x17 => Ok(AnyUInt::MajorByte(x)), x @ 0x18..=0xff => Ok(AnyUInt::U8(x)), }, minicbor::data::Type::U16 => Ok(AnyUInt::U16(d.u16()?)), minicbor::data::Type::U32 => Ok(AnyUInt::U32(d.u32()?)), minicbor::data::Type::U64 => Ok(AnyUInt::U64(d.u64()?)), _ => Err(minicbor::decode::Error::message( "invalid data type for AnyUInt", )), } } } impl minicbor::encode::Encode for AnyUInt { fn encode( &self, e: &mut minicbor::Encoder, _ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { match self { AnyUInt::MajorByte(x) => { let b = &x.to_be_bytes()[..]; e.writer_mut() .write_all(b) .map_err(minicbor::encode::Error::write)?; Ok(()) } AnyUInt::U8(x) => { let x = x.to_be_bytes(); let b = &[[24u8], x].concat()[..]; e.writer_mut() .write_all(b) .map_err(minicbor::encode::Error::write)?; Ok(()) } AnyUInt::U16(x) => { let x = &x.to_be_bytes()[..]; let b = &[&[25u8], x].concat()[..]; e.writer_mut() .write_all(b) .map_err(minicbor::encode::Error::write)?; Ok(()) } AnyUInt::U32(x) => { let x = &x.to_be_bytes()[..]; let b = &[&[26u8], x].concat()[..]; e.writer_mut() .write_all(b) .map_err(minicbor::encode::Error::write)?; Ok(()) } AnyUInt::U64(x) => { let x = &x.to_be_bytes()[..]; let b = &[&[27u8], x].concat()[..]; e.writer_mut() .write_all(b) .map_err(minicbor::encode::Error::write)?; Ok(()) } } } } impl From for u64 { fn from(x: AnyUInt) -> Self { match x { AnyUInt::MajorByte(x) => x as u64, AnyUInt::U8(x) => x as u64, AnyUInt::U16(x) => x as u64, AnyUInt::U32(x) => x as u64, AnyUInt::U64(x) => x as u64, } } } impl From<&AnyUInt> for u64 { fn from(x: &AnyUInt) -> Self { u64::from(*x) } } /// Decodes a struct while preserving original CBOR /// /// # Examples /// /// ``` /// use pallas_codec::utils::KeepRaw; /// /// let a = (123u16, (456u16, 789u16), 123u16); /// let data = minicbor::to_vec(a).unwrap(); /// /// let (_, keeper, _): (u16, KeepRaw<(u16, u16)>, u16) = minicbor::decode(&data).unwrap(); /// let confirm: (u16, u16) = minicbor::decode(keeper.raw_cbor()).unwrap(); /// assert_eq!(confirm, (456u16, 789u16)); /// ``` #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] pub struct KeepRaw<'b, T> { raw: &'b [u8], inner: T, } impl<'b, T> KeepRaw<'b, T> { pub fn raw_cbor(&self) -> &'b [u8] { self.raw } pub fn unwrap(self) -> T { self.inner } } impl<'b, T> Deref for KeepRaw<'b, T> { type Target = T; fn deref(&self) -> &Self::Target { &self.inner } } impl<'b, T, C> minicbor::Decode<'b, C> for KeepRaw<'b, T> where T: minicbor::Decode<'b, C>, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { let all = d.input(); let start = d.position(); let inner: T = d.decode_with(ctx)?; let end = d.position(); Ok(Self { inner, raw: &all[start..end], }) } } impl minicbor::Encode for KeepRaw<'_, T> { fn encode( &self, e: &mut minicbor::Encoder, _ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { e.writer_mut() .write_all(self.raw_cbor()) .map_err(minicbor::encode::Error::write) } } #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(from = "Option::", into = "Option::")] pub enum Nullable where T: std::clone::Clone, { Some(T), Null, Undefined, } impl Nullable where T: std::clone::Clone, { pub fn map(self, f: F) -> Nullable where O: std::clone::Clone, F: Fn(T) -> O, { match self { Nullable::Some(x) => Nullable::Some(f(x)), Nullable::Null => Nullable::Null, Nullable::Undefined => Nullable::Undefined, } } } impl<'b, C, T> minicbor::Decode<'b, C> for Nullable where T: minicbor::Decode<'b, C> + std::clone::Clone, { fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result { match d.datatype()? { minicbor::data::Type::Null => { d.null()?; Ok(Self::Null) } minicbor::data::Type::Undefined => { d.undefined()?; Ok(Self::Undefined) } _ => { let x = d.decode_with(ctx)?; Ok(Self::Some(x)) } } } } impl minicbor::Encode for Nullable where T: minicbor::Encode + std::clone::Clone, { fn encode( &self, e: &mut minicbor::Encoder, ctx: &mut C, ) -> Result<(), minicbor::encode::Error> { match self { Nullable::Some(x) => { e.encode_with(x, ctx)?; Ok(()) } Nullable::Null => { e.null()?; Ok(()) } Nullable::Undefined => { e.undefined()?; Ok(()) } } } } impl From> for Nullable where T: std::clone::Clone, { fn from(x: Option) -> Self { match x { Some(x) => Nullable::Some(x), None => Nullable::Null, } } } impl From> for Option where T: std::clone::Clone, { fn from(other: Nullable) -> Self { match other { Nullable::Some(x) => Some(x), _ => None, } } } #[derive(Serialize, Deserialize, Clone, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord)] #[cbor(transparent)] #[serde(into = "String")] #[serde(try_from = "String")] pub struct Bytes(#[n(0)] minicbor::bytes::ByteVec); impl From> for Bytes { fn from(xs: Vec) -> Self { Bytes(minicbor::bytes::ByteVec::from(xs)) } } impl From for Vec { fn from(b: Bytes) -> Self { b.0.into() } } impl Deref for Bytes { type Target = Vec; fn deref(&self) -> &Self::Target { self.0.deref() } } impl TryFrom for Bytes { type Error = hex::FromHexError; fn try_from(value: String) -> Result { let v = hex::decode(value)?; Ok(Bytes(minicbor::bytes::ByteVec::from(v))) } } impl From for String { fn from(b: Bytes) -> Self { hex::encode(b.deref()) } } #[derive( Serialize, Deserialize, Clone, Copy, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, )] #[cbor(transparent)] #[serde(into = "i128")] #[serde(try_from = "i128")] pub struct Int(#[n(0)] pub minicbor::data::Int); impl Deref for Int { type Target = minicbor::data::Int; fn deref(&self) -> &Self::Target { &self.0 } } impl From for i128 { fn from(value: Int) -> Self { i128::from(value.0) } } impl From for Int { fn from(x: i64) -> Self { let inner = minicbor::data::Int::from(x); Self(inner) } } impl TryFrom for Int { type Error = minicbor::data::TryFromIntError; fn try_from(value: i128) -> Result { let inner = minicbor::data::Int::try_from(value)?; Ok(Self(inner)) } }