cardano_serialization_lib/serialization/plutus/
plutus_data.rs1use crate::*;
2use std::io::SeekFrom;
3use crate::serialization::utils::{is_break_tag, skip_set_tag};
4
5impl cbor_event::se::Serialize for ConstrPlutusData {
6 fn serialize<'se, W: Write>(
7 &self,
8 serializer: &'se mut Serializer<W>,
9 ) -> cbor_event::Result<&'se mut Serializer<W>> {
10 if let Some(compact_tag) =
11 Self::alternative_to_compact_cbor_tag(self.alternative.into())
12 {
13 serializer.write_tag(compact_tag as u64)?;
15 self.data.serialize(serializer)
16 } else {
17 serializer.write_tag(Self::GENERAL_FORM_TAG)?;
19 serializer.write_array(cbor_event::Len::Len(2))?;
20 self.alternative.serialize(serializer)?;
21 self.data.serialize(serializer)
22 }
23 }
24}
25
26impl Deserialize for ConstrPlutusData {
27 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
28 (|| -> Result<_, DeserializeError> {
29 let (alternative, data) = match raw.tag()? {
30 Self::GENERAL_FORM_TAG => {
32 let len = raw.array()?;
33 let mut read_len = CBORReadLen::new(len);
34 read_len.read_elems(2)?;
35 let alternative = BigNum::deserialize(raw)?;
36 let data =
37 (|| -> Result<_, DeserializeError> { Ok(PlutusList::deserialize(raw)?) })()
38 .map_err(|e| e.annotate("datas"))?;
39 match len {
40 cbor_event::Len::Len(_) => (),
41 cbor_event::Len::Indefinite => match raw.special()? {
42 CBORSpecial::Break => (),
43 _ => return Err(DeserializeFailure::EndingBreakMissing.into()),
44 },
45 }
46 (alternative, data)
47 }
48 tag => {
50 if let Some(alternative) = Self::compact_cbor_tag_to_alternative(tag) {
51 (alternative.into(), PlutusList::deserialize(raw)?)
52 } else {
53 return Err(DeserializeFailure::TagMismatch {
54 found: tag,
55 expected: Self::GENERAL_FORM_TAG,
56 }
57 .into());
58 }
59 }
60 };
61 Ok(ConstrPlutusData { alternative, data })
62 })()
63 .map_err(|e| e.annotate("ConstrPlutusData"))
64 }
65}
66
67impl cbor_event::se::Serialize for PlutusMap {
68 fn serialize<'se, W: Write>(
69 &self,
70 serializer: &'se mut Serializer<W>,
71 ) -> cbor_event::Result<&'se mut Serializer<W>> {
72 serializer.write_map(cbor_event::Len::Len(self.total_len() as u64))?;
73 for (key, values) in &self.0 {
74 for value in &values.elems {
75 key.serialize(serializer)?;
76 value.serialize(serializer)?;
77 }
78 }
79 Ok(serializer)
80 }
81}
82
83impl Deserialize for PlutusMap {
84 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
85 let mut plutus_map = PlutusMap::new();
86 (|| -> Result<_, DeserializeError> {
87 let len = raw.map()?;
88 let mut total = 0;
89 while match len {
90 cbor_event::Len::Len(n) => total < n as usize,
91 cbor_event::Len::Indefinite => true,
92 } {
93 if is_break_tag(raw, "PlutusMap")? {
94 break;
95 }
96 let key = PlutusData::deserialize(raw)?;
97 let value = PlutusData::deserialize(raw)?;
98 plutus_map.add_value_move(key, value);
99 total += 1;
100 }
101 Ok(())
102 })()
103 .map_err(|e| e.annotate("PlutusMap"))?;
104 Ok(plutus_map)
105 }
106}
107
108impl cbor_event::se::Serialize for PlutusDataEnum {
109 fn serialize<'se, W: Write>(
110 &self,
111 serializer: &'se mut Serializer<W>,
112 ) -> cbor_event::Result<&'se mut Serializer<W>> {
113 match self {
114 PlutusDataEnum::ConstrPlutusData(x) => x.serialize(serializer),
115 PlutusDataEnum::Map(x) => x.serialize(serializer),
116 PlutusDataEnum::List(x) => x.serialize(serializer),
117 PlutusDataEnum::Integer(x) => x.serialize(serializer),
118 PlutusDataEnum::Bytes(x) => write_bounded_bytes(serializer, &x),
119 }
120 }
121}
122
123impl Deserialize for PlutusDataEnum {
124 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
125 (|| -> Result<_, DeserializeError> {
126 let initial_position = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap();
127 match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
128 Ok(ConstrPlutusData::deserialize(raw)?)
129 })(raw)
130 {
131 Ok(variant) => return Ok(PlutusDataEnum::ConstrPlutusData(variant)),
132 Err(_) => raw
133 .as_mut_ref()
134 .seek(SeekFrom::Start(initial_position))
135 .unwrap(),
136 };
137 match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
138 Ok(PlutusMap::deserialize(raw)?)
139 })(raw)
140 {
141 Ok(variant) => return Ok(PlutusDataEnum::Map(variant)),
142 Err(_) => raw
143 .as_mut_ref()
144 .seek(SeekFrom::Start(initial_position))
145 .unwrap(),
146 };
147 match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
148 Ok(PlutusList::deserialize(raw)?)
149 })(raw)
150 {
151 Ok(variant) => return Ok(PlutusDataEnum::List(variant)),
152 Err(_) => raw
153 .as_mut_ref()
154 .seek(SeekFrom::Start(initial_position))
155 .unwrap(),
156 };
157 match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
158 Ok(BigInt::deserialize(raw)?)
159 })(raw)
160 {
161 Ok(variant) => return Ok(PlutusDataEnum::Integer(variant)),
162 Err(_) => raw
163 .as_mut_ref()
164 .seek(SeekFrom::Start(initial_position))
165 .unwrap(),
166 };
167 match (|raw: &mut Deserializer<_>| -> Result<_, DeserializeError> {
168 Ok(read_bounded_bytes(raw)?)
169 })(raw)
170 {
171 Ok(variant) => return Ok(PlutusDataEnum::Bytes(variant)),
172 Err(_) => raw
173 .as_mut_ref()
174 .seek(SeekFrom::Start(initial_position))
175 .unwrap(),
176 };
177 Err(DeserializeError::new(
178 "PlutusDataEnum",
179 DeserializeFailure::NoVariantMatched.into(),
180 ))
181 })()
182 .map_err(|e| e.annotate("PlutusDataEnum"))
183 }
184}
185
186impl cbor_event::se::Serialize for PlutusData {
187 fn serialize<'se, W: Write>(
188 &self,
189 serializer: &'se mut Serializer<W>,
190 ) -> cbor_event::Result<&'se mut Serializer<W>> {
191 match &self.original_bytes {
192 Some(bytes) => serializer.write_raw_bytes(bytes),
193 None => self.datum.serialize(serializer),
194 }
195 }
196}
197
198impl Deserialize for PlutusData {
199 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
200 let before = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap();
202 let datum = PlutusDataEnum::deserialize(raw)?;
203 let after = raw.as_mut_ref().seek(SeekFrom::Current(0)).unwrap();
204 let bytes_read = (after - before) as usize;
205 raw.as_mut_ref().seek(SeekFrom::Start(before)).unwrap();
206 let original_bytes = raw.as_mut_ref().fill_buf().unwrap()[..bytes_read].to_vec();
208 raw.as_mut_ref().consume(bytes_read);
209 Ok(Self {
210 datum,
211 original_bytes: Some(original_bytes),
212 })
213 }
214}
215
216impl cbor_event::se::Serialize for PlutusList {
217 fn serialize<'se, W: Write>(
218 &self,
219 serializer: &'se mut Serializer<W>,
220 ) -> cbor_event::Result<&'se mut Serializer<W>> {
221 let use_definite_encoding = match self.definite_encoding {
222 Some(definite) => definite,
223 None => self.elems.is_empty(),
224 };
225 if use_definite_encoding {
226 serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?;
227 } else {
228 serializer.write_array(cbor_event::Len::Indefinite)?;
229 }
230 for element in &self.elems {
231 element.serialize(serializer)?;
232 }
233 if !use_definite_encoding {
234 serializer.write_special(cbor_event::Special::Break)?;
235 }
236 Ok(serializer)
237 }
238}
239
240impl PlutusList {
241 pub(crate) fn serialize_as_set<'se, W: Write>(
242 &self,
243 need_deduplication: bool,
244 serializer: &'se mut Serializer<W>,
245 ) -> cbor_event::Result<&'se mut Serializer<W>> {
246 serializer.write_tag(258)?;
247 let use_definite_encoding = match self.definite_encoding {
248 Some(definite) => definite,
249 None => self.elems.is_empty(),
250 };
251 if use_definite_encoding {
252 serializer.write_array(cbor_event::Len::Len(self.elems.len() as u64))?;
253 } else {
254 serializer.write_array(cbor_event::Len::Indefinite)?;
255 }
256 if need_deduplication {
257 for element in self.deduplicated_view() {
258 element.serialize(serializer)?;
259 }
260 } else {
261 for element in &self.elems {
262 element.serialize(serializer)?;
263 }
264 }
265 if !use_definite_encoding {
266 serializer.write_special(cbor_event::Special::Break)?;
267 }
268 Ok(serializer)
269 }
270}
271
272impl Deserialize for PlutusList {
273 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
274 let has_set_tag = skip_set_tag(raw)?;
275 let mut arr = Vec::new();
276 let len = (|| -> Result<_, DeserializeError> {
277 let len = raw.array()?;
278 while match len {
279 cbor_event::Len::Len(n) => arr.len() < n as usize,
280 cbor_event::Len::Indefinite => true,
281 } {
282 if is_break_tag(raw, "PlutusList")? {
283 break;
284 }
285 arr.push(PlutusData::deserialize(raw)?);
286 }
287 Ok(len)
288 })()
289 .map_err(|e| e.annotate("PlutusList"))?;
290
291 let set_tag = if has_set_tag {
292 Some(CborSetType::Tagged)
293 } else {
294 Some(CborSetType::Untagged)
295 };
296
297 Ok(Self {
298 elems: arr,
299 definite_encoding: Some(len != cbor_event::Len::Indefinite),
300 cbor_set_type: set_tag
301 })
302 }
303}