use crate::*;
use std::io::SeekFrom;
use crate::serialization::utils::{is_break_tag, skip_set_tag};
impl cbor_event::se::Serialize for ConstrPlutusData {
fn serialize<'se, W: Write>(
&self,
serializer: &'se mut Serializer<W>,
) -> cbor_event::Result<&'se mut Serializer<W>> {
if let Some(compact_tag) =
Self::alternative_to_compact_cbor_tag(self.alternative.into())
{
serializer.write_tag(compact_tag as u64)?;
self.data.serialize(serializer)
} else {
serializer.write_tag(Self::GENERAL_FORM_TAG)?;
serializer.write_array(cbor_event::Len::Len(2))?;
self.alternative.serialize(serializer)?;
self.data.serialize(serializer)
}
}
}
impl Deserialize for ConstrPlutusData {
fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
(|| -> Result<_, DeserializeError> {
let (alternative, data) = match raw.tag()? {
Self::GENERAL_FORM_TAG => {
let len = raw.array()?;
let mut read_len = CBORReadLen::new(len);
read_len.read_elems(2)?;
let alternative = BigNum::deserialize(raw)?;
let data =
(|| -> Result<_, DeserializeError> { Ok(PlutusList::deserialize(raw)?) })()
.map_err(|e| e.annotate("datas"))?;
match len {
cbor_event::Len::Len(_) => (),
cbor_event::Len::Indefinite => match raw.special()? {
CBORSpecial::Break => (),
_ => return Err(DeserializeFailure::EndingBreakMissing.into()),
},
}
(alternative, data)
}
tag => {
if let Some(alternative) = Self::compact_cbor_tag_to_alternative(tag) {
(alternative.into(), PlutusList::deserialize(raw)?)
} else {
return Err(DeserializeFailure::TagMismatch {
found: tag,
expected: Self::GENERAL_FORM_TAG,
}
.into());
}
}
};
Ok(ConstrPlutusData { alternative, data })
})()
.map_err(|e| e.annotate("ConstrPlutusData"))
}
}
impl cbor_event::se::Serialize for PlutusMap {
fn serialize<'se, W: Write>(
&self,
serializer: &'se mut Serializer<W>,
) -> cbor_event::Result<&'se mut Serializer<W>> {
serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?;
for (key, values) in &self.0 {
for value in &values.elems {
key.serialize(serializer)?;
value.serialize(serializer)?;
}
}
Ok(serializer)
}
}
impl Deserialize for PlutusMap {
fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
let mut plutus_map = PlutusMap::new();
(|| -> Result<_, DeserializeError> {
let len = raw.map()?;
let mut total = 0;
while match len {
cbor_event::Len::Len(n) => total < n as usize,
cbor_event::Len::Indefinite => true,
} {
if is_break_tag(raw, "PlutusMap")? {
break;
}
let key = PlutusData::deserialize(raw)?;
let value = PlutusData::deserialize(raw)?;
plutus_map.add_value_move(key, value);
total += 1;
}
Ok(())
})()
.map_err(|e| e.annotate("PlutusMap"))?;
Ok(plutus_map)
}
}
impl cbor_event::se::Serialize for PlutusDataEnum {
fn serialize<'se, W: Write>(
&self,
serializer: &'se mut Serializer<W>,
) -> cbor_event::Result<&'se mut Serializer<W>> {
match self {
PlutusDataEnum::ConstrPlutusData(x) => x.serialize(serializer),
PlutusDataEnum::Map(x) => x.serialize(serializer),
PlutusDataEnum::List(x) => x.serialize(serializer),
PlutusDataEnum::Integer(x) => x.serialize(serializer),
PlutusDataEnum::Bytes(x) => write_bounded_bytes(serializer, &x),
}
}
}
impl Deserialize for PlutusDataEnum {
fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
(|| -> Result<_, DeserializeError> {
let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap();
match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
Ok(ConstrPlutusData::deserialize(raw)?)
})(raw)
{
Ok(variant) => return Ok(PlutusDataEnum::ConstrPlutusData(variant)),
Err(_) => raw
.as_mut_ref()
.seek(SeekFrom::Start(initial_position))
.unwrap(),
};
match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
Ok(PlutusMap::deserialize(raw)?)
})(raw)
{
Ok(variant) => return Ok(PlutusDataEnum::Map(variant)),
Err(_) => raw
.as_mut_ref()
.seek(SeekFrom::Start(initial_position))
.unwrap(),
};
match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
Ok(PlutusList::deserialize(raw)?)
})(raw)
{
Ok(variant) => return Ok(PlutusDataEnum::List(variant)),
Err(_) => raw
.as_mut_ref()
.seek(SeekFrom::Start(initial_position))
.unwrap(),
};
match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
Ok(BigInt::deserialize(raw)?)
})(raw)
{
Ok(variant) => return Ok(PlutusDataEnum::Integer(variant)),
Err(_) => raw
.as_mut_ref()
.seek(SeekFrom::Start(initial_position))
.unwrap(),
};
match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
Ok(read_bounded_bytes(raw)?)
})(raw)
{
Ok(variant) => return Ok(PlutusDataEnum::Bytes(variant)),
Err(_) => raw
.as_mut_ref()
.seek(SeekFrom::Start(initial_position))
.unwrap(),
};
Err(DeserializeError::new(
"PlutusDataEnum",
DeserializeFailure::NoVariantMatched.into(),
))
})()
.map_err(|e| e.annotate("PlutusDataEnum"))
}
}
impl cbor_event::se::Serialize for PlutusData {
fn serialize<'se, W: Write>(
&self,
serializer: &'se mut Serializer<W>,
) -> cbor_event::Result<&'se mut Serializer<W>> {
match &self.original_bytes {
Some(bytes) => serializer.write_raw_bytes(bytes),
None => self.datum.serialize(serializer),
}
}
}
impl Deserialize for PlutusData {
fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap();
let datum = PlutusDataEnum::deserialize(raw)?;
let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap();
let bytes_read = (after - before) as usize;
raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap();
let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec();
raw.as_mut_ref().consume(bytes_read);
Ok(Self {
datum,
original_bytes: Some(original_bytes),
})
}
}
impl cbor_event::se::Serialize for PlutusList {
fn serialize<'se, W: Write>(
&self,
serializer: &'se mut Serializer<W>,
) -> cbor_event::Result<&'se mut Serializer<W>> {
let use_definite_encoding = match self.definite_encoding {
Some(definite) => definite,
None => self.elems.is_empty(),
};
if use_definite_encoding {
serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?;
} else {
serializer.write_array(cbor_event::Len::Indefinite)?;
}
for element in &self.elems {
element.serialize(serializer)?;
}
if !use_definite_encoding {
serializer.write_special(cbor_event::Special::Break)?;
}
Ok(serializer)
}
}
impl PlutusList {
pub(crate) fn serialize_as_set<'se, W: Write>(
&self,
need_deduplication: bool,
serializer: &'se mut Serializer<W>,
) -> cbor_event::Result<&'se mut Serializer<W>> {
let use_definite_encoding = match self.definite_encoding {
Some(definite) => definite,
None => self.elems.is_empty(),
};
if use_definite_encoding {
serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?;
} else {
serializer.write_array(cbor_event::Len::Indefinite)?;
}
if need_deduplication {
for element in self.deduplicated_view() {
element.serialize(serializer)?;
}
} else {
for element in &self.elems {
element.serialize(serializer)?;
}
}
if !use_definite_encoding {
serializer.write_special(cbor_event::Special::Break)?;
}
Ok(serializer)
}
}
impl Deserialize for PlutusList {
fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
skip_set_tag(raw)?;
let mut arr = Vec::new();
let len = (|| -> Result<_, DeserializeError> {
let len = raw.array()?;
while match len {
cbor_event::Len::Len(n) => arr.len() < n as usize,
cbor_event::Len::Indefinite => true,
} {
if is_break_tag(raw, "PlutusList")? {
break;
}
arr.push(PlutusData::deserialize(raw)?);
}
Ok(len)
})()
.map_err(|e| e.annotate("PlutusList"))?;
Ok(Self {
elems: arr,
definite_encoding: Some(len != cbor_event::Len::Indefinite),
})
}
}