cardano_serialization_lib/serialization/
metadata.rs1use hashlink::LinkedHashMap;
2use crate::*;
3use crate::serialization::utils::{is_break_tag, merge_option_plutus_list};
4
5impl cbor_event::se::Serialize for MetadataMap {
6 fn serialize<'se, W: Write>(
7 &self,
8 serializer: &'se mut Serializer<W>,
9 ) -> cbor_event::Result<&'se mut Serializer<W>> {
10 serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?;
11 for (key, value) in &self.0 {
12 key.serialize(serializer)?;
13 value.serialize(serializer)?;
14 }
15 Ok(serializer)
16 }
17}
18
19impl Deserialize for MetadataMap {
20 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
21 let mut table = LinkedHashMap::new();
22 let mut entries: Vec<(TransactionMetadatum, TransactionMetadatum)> = Vec::new();
23 (|| -> Result<_, DeserializeError> {
24 let len = raw.map()?;
25 while match len {
26 cbor_event::Len::Len(n) => entries.len() < n as usize,
27 cbor_event::Len::Indefinite => true,
28 } {
29 if is_break_tag(raw, "MetadataMap")? {
30 break;
31 }
32 let key = TransactionMetadatum::deserialize(raw)?;
33 let value = TransactionMetadatum::deserialize(raw)?;
34 entries.push((key.clone(), value));
35 }
36 Ok(())
37 })()
38 .map_err(|e| e.annotate("MetadataMap"))?;
39 entries.iter().for_each(|(k, v)| {
40 if table.insert(k.clone(), v.clone()).is_some() {
41 }
44 });
45 Ok(Self(table))
46 }
47}
48
49impl cbor_event::se::Serialize for MetadataList {
50 fn serialize<'se, W: Write>(
51 &self,
52 serializer: &'se mut Serializer<W>,
53 ) -> cbor_event::Result<&'se mut Serializer<W>> {
54 serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?;
55 for element in &self.0 {
56 element.serialize(serializer)?;
57 }
58 Ok(serializer)
59 }
60}
61
62impl Deserialize for MetadataList {
63 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
64 let mut arr = Vec::new();
65 (|| -> Result<_, DeserializeError> {
66 let len = raw.array()?;
67 while match len {
68 cbor_event::Len::Len(n) => arr.len() < n as usize,
69 cbor_event::Len::Indefinite => true,
70 } {
71 if is_break_tag(raw, "MetadataList")? {
72 break;
73 }
74 arr.push(TransactionMetadatum::deserialize(raw)?);
75 }
76 Ok(())
77 })()
78 .map_err(|e| e.annotate("MetadataList"))?;
79 Ok(Self(arr))
80 }
81}
82
83impl cbor_event::se::Serialize for TransactionMetadatumEnum {
84 fn serialize<'se, W: Write>(
85 &self,
86 serializer: &'se mut Serializer<W>,
87 ) -> cbor_event::Result<&'se mut Serializer<W>> {
88 match self {
89 TransactionMetadatumEnum::MetadataMap(x) => x.serialize(serializer),
90 TransactionMetadatumEnum::MetadataList(x) => x.serialize(serializer),
91 TransactionMetadatumEnum::Int(x) => x.serialize(serializer),
92 TransactionMetadatumEnum::Bytes(x) => serializer.write_bytes(&x),
93 TransactionMetadatumEnum::Text(x) => serializer.write_text(&x),
94 }
95 }
96}
97
98impl Deserialize for TransactionMetadatumEnum {
99 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
100 match raw.cbor_type()? {
101 CBORType::Array => {
102 MetadataList::deserialize(raw).map(TransactionMetadatumEnum::MetadataList)
103 }
104 CBORType::Map => {
105 MetadataMap::deserialize(raw).map(TransactionMetadatumEnum::MetadataMap)
106 }
107 CBORType::Bytes => TransactionMetadatum::new_bytes(raw.bytes()?)
108 .map(|m| m.0)
109 .map_err(|e| DeserializeFailure::Metadata(e).into()),
110 CBORType::Text => TransactionMetadatum::new_text(raw.text()?)
111 .map(|m| m.0)
112 .map_err(|e| DeserializeFailure::Metadata(e).into()),
113 CBORType::UnsignedInteger | CBORType::NegativeInteger => {
114 Int::deserialize(raw).map(TransactionMetadatumEnum::Int)
115 }
116 _ => Err(DeserializeError::new(
117 "TransactionMetadatumEnum",
118 DeserializeFailure::NoVariantMatched.into(),
119 )),
120 }
121 }
122}
123
124impl cbor_event::se::Serialize for TransactionMetadatum {
125 fn serialize<'se, W: Write>(
126 &self,
127 serializer: &'se mut Serializer<W>,
128 ) -> cbor_event::Result<&'se mut Serializer<W>> {
129 self.0.serialize(serializer)
130 }
131}
132
133impl Deserialize for TransactionMetadatum {
134 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
135 Ok(Self(TransactionMetadatumEnum::deserialize(raw)?))
136 }
137}
138
139impl cbor_event::se::Serialize for TransactionMetadatumLabels {
140 fn serialize<'se, W: Write>(
141 &self,
142 serializer: &'se mut Serializer<W>,
143 ) -> cbor_event::Result<&'se mut Serializer<W>> {
144 serializer.write_array(cbor_event::Len::Len(self.0.len() as u64))?;
145 for element in &self.0 {
146 element.serialize(serializer)?;
147 }
148 Ok(serializer)
149 }
150}
151
152impl Deserialize for TransactionMetadatumLabels {
153 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
154 let mut arr = Vec::new();
155 (|| -> Result<_, DeserializeError> {
156 let len = raw.array()?;
157 while match len {
158 cbor_event::Len::Len(n) => arr.len() < n as usize,
159 cbor_event::Len::Indefinite => true,
160 } {
161 if is_break_tag(raw, "TransactionMetadatumLabels")? {
162 break;
163 }
164 arr.push(TransactionMetadatumLabel::deserialize(raw)?);
165 }
166 Ok(())
167 })()
168 .map_err(|e| e.annotate("TransactionMetadatumLabels"))?;
169 Ok(Self(arr))
170 }
171}
172
173impl cbor_event::se::Serialize for GeneralTransactionMetadata {
174 fn serialize<'se, W: Write>(
175 &self,
176 serializer: &'se mut Serializer<W>,
177 ) -> cbor_event::Result<&'se mut Serializer<W>> {
178 serializer.write_map(cbor_event::Len::Len(self.0.len() as u64))?;
179 for (key, value) in &self.0 {
180 key.serialize(serializer)?;
181 value.serialize(serializer)?;
182 }
183 Ok(serializer)
184 }
185}
186
187impl Deserialize for GeneralTransactionMetadata {
188 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
189 let mut table = LinkedHashMap::new();
190 (|| -> Result<_, DeserializeError> {
191 let len = raw.map()?;
192 while match len {
193 cbor_event::Len::Len(n) => table.len() < n as usize,
194 cbor_event::Len::Indefinite => true,
195 } {
196 if is_break_tag(raw, "GeneralTransactionMetadata")? {
197 break;
198 }
199 let key = TransactionMetadatumLabel::deserialize(raw)?;
200 let value = TransactionMetadatum::deserialize(raw)?;
201 if table.insert(key.clone(), value).is_some() {
202 return Err(DeserializeFailure::DuplicateKey(Key::Str(String::from(
203 "some complicated/unsupported type",
204 )))
205 .into());
206 }
207 }
208 Ok(())
209 })()
210 .map_err(|e| e.annotate("GeneralTransactionMetadata"))?;
211 Ok(Self(table))
212 }
213}
214
215impl cbor_event::se::Serialize for AuxiliaryData {
216 fn serialize<'se, W: Write>(
217 &self,
218 serializer: &'se mut Serializer<W>,
219 ) -> cbor_event::Result<&'se mut Serializer<W>> {
220 if !self.prefer_alonzo_format && self.metadata.is_some() && self.plutus_scripts.is_none() {
224 match &self.native_scripts() {
225 Some(native_scripts) => {
226 serializer.write_array(cbor_event::Len::Len(2))?;
227 self.metadata.as_ref().unwrap().serialize(serializer)?;
228 native_scripts.serialize(serializer)
229 }
230 None => self.metadata.as_ref().unwrap().serialize(serializer),
231 }
232 } else {
233 let mut has_plutus_v2 = false;
234 let mut has_plutus_v3 = false;
235 let plutus_added_length = match &self.plutus_scripts {
236 Some(scripts) => {
237 has_plutus_v2 = scripts.has_version(&Language::new_plutus_v2());
238 has_plutus_v3 = scripts.has_version(&Language::new_plutus_v3());
239 1 + (has_plutus_v2 as u64) + (has_plutus_v3 as u64)
240 },
241 _ => 0,
242 };
243
244 serializer.write_tag(259u64)?;
246 serializer.write_map(cbor_event::Len::Len(
247 opt64(&self.metadata) + opt64(&self.native_scripts) + plutus_added_length,
248 ))?;
249 if let Some(metadata) = &self.metadata {
250 serializer.write_unsigned_integer(0)?;
251 metadata.serialize(serializer)?;
252 }
253 if let Some(native_scripts) = &self.native_scripts {
254 serializer.write_unsigned_integer(1)?;
255 native_scripts.serialize(serializer)?;
256 }
257 if let Some(plutus_scripts) = &self.plutus_scripts {
258 serializer.write_unsigned_integer(2)?;
259 plutus_scripts.serialize_by_version(&Language::new_plutus_v1(), serializer)?;
260 if has_plutus_v2 {
261 serializer.write_unsigned_integer(3)?;
262 plutus_scripts.serialize_by_version(&Language::new_plutus_v2(), serializer)?;
263 }
264 if has_plutus_v3 {
265 serializer.write_unsigned_integer(4)?;
266 plutus_scripts.serialize_by_version(&Language::new_plutus_v3(), serializer)?;
267 }
268 }
269 Ok(serializer)
270 }
271 }
272}
273
274impl Deserialize for AuxiliaryData {
275 fn deserialize<R: BufRead + Seek>(raw: &mut Deserializer<R>) -> Result<Self, DeserializeError> {
276 (|| -> Result<_, DeserializeError> {
277 match raw.cbor_type()? {
278 CBORType::Tag => {
280 let tag = raw.tag()?;
281 if tag != 259 {
282 return Err(DeserializeError::new(
283 "AuxiliaryData",
284 DeserializeFailure::TagMismatch {
285 found: tag,
286 expected: 259,
287 },
288 ));
289 }
290 let len = raw.map()?;
291 let mut read_len = CBORReadLen::new(len);
292 let mut metadata = None;
293 let mut native_scripts = None;
294 let mut plutus_scripts_v1 = None;
295 let mut plutus_scripts_v2 = None;
296 let mut plutus_scripts_v3 = None;
297 let mut read = 0;
298 while match len {
299 cbor_event::Len::Len(n) => read < n as usize,
300 cbor_event::Len::Indefinite => true,
301 } {
302 match raw.cbor_type()? {
303 CBORType::UnsignedInteger => match raw.unsigned_integer()? {
304 0 => {
305 if metadata.is_some() {
306 return Err(
307 DeserializeFailure::DuplicateKey(Key::Uint(0)).into()
308 );
309 }
310 metadata = Some(
311 (|| -> Result<_, DeserializeError> {
312 read_len.read_elems(1)?;
313 Ok(GeneralTransactionMetadata::deserialize(raw)?)
314 })()
315 .map_err(|e| e.annotate("metadata"))?,
316 );
317 }
318 1 => {
319 if native_scripts.is_some() {
320 return Err(
321 DeserializeFailure::DuplicateKey(Key::Uint(1)).into()
322 );
323 }
324 native_scripts = Some(
325 (|| -> Result<_, DeserializeError> {
326 read_len.read_elems(1)?;
327 Ok(NativeScripts::deserialize(raw)?)
328 })()
329 .map_err(|e| e.annotate("native_scripts"))?,
330 );
331 }
332 2 => {
333 if plutus_scripts_v1.is_some() {
334 return Err(
335 DeserializeFailure::DuplicateKey(Key::Uint(2)).into()
336 );
337 }
338 plutus_scripts_v1 = Some(
339 (|| -> Result<_, DeserializeError> {
340 read_len.read_elems(1)?;
341 Ok(PlutusScripts::deserialize(raw)?)
342 })()
343 .map_err(|e| e.annotate("plutus_scripts_v1"))?,
344 );
345 }
346 3 => {
347 if plutus_scripts_v2.is_some() {
348 return Err(
349 DeserializeFailure::DuplicateKey(Key::Uint(3)).into()
350 );
351 }
352 plutus_scripts_v2 = Some(
353 (|| -> Result<_, DeserializeError> {
354 read_len.read_elems(1)?;
355 Ok(PlutusScripts::deserialize_with_version(raw, &Language::new_plutus_v2())?)
356 })()
357 .map_err(|e| e.annotate("plutus_scripts_v2"))?,
358 );
359 }
360 4 => {
361 if plutus_scripts_v3.is_some() {
362 return Err(
363 DeserializeFailure::DuplicateKey(Key::Uint(3)).into()
364 );
365 }
366 plutus_scripts_v3 = Some(
367 (|| -> Result<_, DeserializeError> {
368 read_len.read_elems(1)?;
369 Ok(PlutusScripts::deserialize_with_version(raw, &Language::new_plutus_v3())?)
370 })()
371 .map_err(|e| e.annotate("plutus_scripts_v3"))?,
372 );
373 }
374 unknown_key => {
375 return Err(DeserializeFailure::UnknownKey(Key::Uint(
376 unknown_key,
377 ))
378 .into())
379 }
380 },
381 CBORType::Text => match raw.text()?.as_str() {
382 unknown_key => {
383 return Err(DeserializeFailure::UnknownKey(Key::Str(
384 unknown_key.to_owned(),
385 ))
386 .into())
387 }
388 },
389 CBORType::Special => match len {
390 cbor_event::Len::Len(_) => {
391 return Err(DeserializeFailure::BreakInDefiniteLen.into())
392 }
393 cbor_event::Len::Indefinite => match raw.special()? {
394 CBORSpecial::Break => break,
395 _ => return Err(DeserializeFailure::EndingBreakMissing.into()),
396 },
397 },
398 other_type => {
399 return Err(DeserializeFailure::UnexpectedKeyType(other_type).into())
400 }
401 }
402 read += 1;
403 }
404 read_len.finish()?;
405 let mut plutus_scripts = None;
406 plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v1, &Language::new_plutus_v1());
407 plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v2, &Language::new_plutus_v2());
408 plutus_scripts = merge_option_plutus_list(plutus_scripts, plutus_scripts_v3, &Language::new_plutus_v3());
409
410 Ok(Self {
411 metadata,
412 native_scripts,
413 plutus_scripts,
414 prefer_alonzo_format: true,
415 })
416 }
417 CBORType::Array => {
419 let len = raw.array()?;
420 let mut read_len = CBORReadLen::new(len);
421 read_len.read_elems(2)?;
422 let metadata = (|| -> Result<_, DeserializeError> {
423 Ok(GeneralTransactionMetadata::deserialize(raw)?)
424 })()
425 .map_err(|e| e.annotate("metadata"))?;
426 let native_scripts = (|| -> Result<_, DeserializeError> {
427 Ok(NativeScripts::deserialize(raw)?)
428 })()
429 .map_err(|e| e.annotate("native_scripts"))?;
430 match len {
431 cbor_event::Len::Len(_) => (),
432 cbor_event::Len::Indefinite => match raw.special()? {
433 CBORSpecial::Break => (),
434 _ => return Err(DeserializeFailure::EndingBreakMissing.into()),
435 },
436 }
437 Ok(Self {
438 metadata: Some(metadata),
439 native_scripts: Some(native_scripts),
440 plutus_scripts: None,
441 prefer_alonzo_format: false,
442 })
443 }
444 CBORType::Map => Ok(Self {
446 metadata: Some(
447 GeneralTransactionMetadata::deserialize(raw)
448 .map_err(|e| e.annotate("metadata"))?,
449 ),
450 native_scripts: None,
451 plutus_scripts: None,
452 prefer_alonzo_format: false,
453 }),
454 _ => return Err(DeserializeFailure::NoVariantMatched)?,
455 }
456 })()
457 .map_err(|e| e.annotate("AuxiliaryData"))
458 }
459}