feat(codec): add utility for untyped CBOR fragments (#327)

This commit is contained in:
Santiago Carmuega 2023-11-09 18:22:42 -03:00 committed by GitHub
parent 68b46c36a8
commit aae7d92b44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -649,6 +649,86 @@ impl<C, T> minicbor::Encode<C> for KeepRaw<'_, T> {
}
}
/// Struct to hold arbitrary CBOR to be processed independently
///
/// # Examples
///
/// ```
/// use pallas_codec::utils::AnyCbor;
///
/// let a = (123u16, (456u16, 789u16), 123u16);
/// let data = minicbor::to_vec(a).unwrap();
///
/// let (_, any, _): (u16, AnyCbor, u16) = minicbor::decode(&data).unwrap();
/// let confirm: (u16, u16) = any.into_decode().unwrap();
/// assert_eq!(confirm, (456u16, 789u16));
/// ```
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct AnyCbor {
inner: Vec<u8>,
}
impl AnyCbor {
pub fn raw_bytes(&self) -> &[u8] {
&self.inner
}
pub fn unwrap(self) -> Vec<u8> {
self.inner
}
pub fn from_encode<T>(other: T) -> Self
where
T: Encode<()>,
{
let inner = minicbor::to_vec(other).unwrap();
Self { inner }
}
pub fn into_decode<T>(self) -> Result<T, minicbor::decode::Error>
where
for<'b> T: Decode<'b, ()>,
{
minicbor::decode(&self.inner)
}
}
impl Deref for AnyCbor {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<'b, C> minicbor::Decode<'b, C> for AnyCbor {
fn decode(
d: &mut minicbor::Decoder<'b>,
_ctx: &mut C,
) -> Result<Self, minicbor::decode::Error> {
let all = d.input();
let start = d.position();
d.skip()?;
let end = d.position();
Ok(Self {
inner: Vec::from(&all[start..end]),
})
}
}
impl<C> minicbor::Encode<C> for AnyCbor {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
_ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
e.writer_mut()
.write_all(self.raw_bytes())
.map_err(minicbor::encode::Error::write)
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(from = "Option::<T>", into = "Option::<T>")]
pub enum Nullable<T>