tx_bakery/
metadata.rs

1//! Transaction Metadata
2
3use std::collections::BTreeMap;
4
5use anyhow::anyhow;
6use plutus_ledger_api::csl::{lib as csl, pla_to_csl::TryToCSL};
7
8use crate::error::Error;
9
10/// Top level transaction metadata (can only be a Map)
11#[derive(Debug, Clone)]
12pub struct TransactionMetadata(pub BTreeMap<u64, Metadata>);
13
14impl TryFrom<&TransactionMetadata> for csl::GeneralTransactionMetadata {
15    type Error = Error;
16
17    fn try_from(tx_metadata: &TransactionMetadata) -> Result<Self, Self::Error> {
18        let mut csl_tx_metadata = csl::GeneralTransactionMetadata::new();
19
20        tx_metadata.0.iter().try_for_each(|(key, value)| {
21            let _ = csl_tx_metadata.insert(&csl::BigNum::from(*key), &value.try_into()?);
22            Ok::<(), Self::Error>(())
23        })?;
24
25        Ok(csl_tx_metadata)
26    }
27}
28
29impl<const N: usize> From<[(u64, Metadata); N]> for TransactionMetadata {
30    fn from(arr: [(u64, Metadata); N]) -> Self {
31        TransactionMetadata(BTreeMap::from(arr))
32    }
33}
34
35/// Transaction Metadata
36#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
37pub enum Metadata {
38    Map(BTreeMap<Metadata, Metadata>),
39    List(Vec<Metadata>),
40    Int(i64),
41    Bytes(Vec<u8>),
42    Text(String),
43}
44
45impl TryFrom<&Metadata> for csl::TransactionMetadatum {
46    type Error = Error;
47
48    fn try_from(metadata: &Metadata) -> Result<Self, Self::Error> {
49        match metadata {
50            Metadata::Map(metadata_map) => {
51                let mut csl_metadata_map = csl::MetadataMap::new();
52
53                metadata_map.iter().try_for_each(|(key, value)| {
54                    let _ = csl_metadata_map.insert(&key.try_into()?, &value.try_into()?);
55                    Ok::<(), Self::Error>(())
56                })?;
57
58                Ok(csl::TransactionMetadatum::new_map(&csl_metadata_map))
59            }
60
61            Metadata::List(metadata_list) => {
62                let mut csl_metadata_list = csl::MetadataList::new();
63
64                metadata_list.iter().try_for_each(|elem| {
65                    csl_metadata_list.add(&elem.try_into()?);
66                    Ok::<(), Self::Error>(())
67                })?;
68
69                Ok(csl::TransactionMetadatum::new_list(&csl_metadata_list))
70            }
71
72            Metadata::Int(int) => Ok(csl::TransactionMetadatum::new_int(&int.try_to_csl()?)),
73
74            Metadata::Bytes(bytes) => csl::TransactionMetadatum::new_bytes(bytes.to_owned())
75                .map_err(|source| {
76                    Error::ConversionError(anyhow!(
77                        "Metadata::Bytes could not be converted: {}",
78                        source
79                    ))
80                }),
81
82            Metadata::Text(str) => {
83                csl::TransactionMetadatum::new_text(str.to_owned()).map_err(|source| {
84                    Error::ConversionError(anyhow!(
85                        "Metadata::Text could not be converted: {}",
86                        source
87                    ))
88                })
89            }
90        }
91    }
92}