1#![no_std]
17#![deny(missing_docs)]
18
19mod cbor;
20
21extern crate alloc;
22
23use crate::Datum::*;
24#[doc(hidden)]
25pub use alloc::{vec, vec::Vec};
26use core::fmt::{Debug, Formatter};
27use num_bigint::BigInt;
28
29#[derive(Clone, PartialEq)]
31pub enum Datum {
32 IntegerDatum(BigInt),
34 ByteStringDatum(Vec<u8>),
36 ConstructorDatum {
43 constructor: u64,
45 fields: Vec<Datum>,
47 },
48 ListDatum(Vec<Datum>),
50 MapDatum(Vec<MapDatumEntry>),
52}
53
54#[derive(Clone, Debug, PartialEq)]
56pub struct MapDatumEntry {
57 key: Datum,
59 value: Datum,
61}
62
63pub trait ToDatum {
65 fn to_datum(&self) -> Datum;
67}
68
69impl ToDatum for Vec<u8> {
70 fn to_datum(&self) -> Datum {
71 ByteStringDatum(self.clone())
72 }
73}
74
75impl ToDatum for [u8] {
76 fn to_datum(&self) -> Datum {
77 ByteStringDatum(Vec::from(self))
78 }
79}
80
81impl<T: ToDatum> ToDatum for Option<T> {
82 fn to_datum(&self) -> Datum {
83 match self {
84 Some(value) => ConstructorDatum { constructor: 0, fields: vec![value.to_datum()] },
85 None => ConstructorDatum { constructor: 1, fields: vec![] },
86 }
87 }
88}
89
90impl<T> ToDatum for [T]
91where
92 T: ToDatum,
93{
94 fn to_datum(&self) -> Datum {
95 ListDatum(self.iter().map(ToDatum::to_datum).collect())
96 }
97}
98
99impl<T> ToDatum for Vec<T>
100where
101 T: ToDatum,
102{
103 fn to_datum(&self) -> Datum {
104 ListDatum(self.iter().map(ToDatum::to_datum).collect())
105 }
106}
107
108impl ToDatum for Datum {
109 fn to_datum(&self) -> Datum {
110 self.clone()
111 }
112}
113
114impl Datum {
115 fn integer<T>(value: T) -> Datum
116 where
117 BigInt: From<T>,
118 {
119 IntegerDatum(BigInt::from(value))
120 }
121
122 pub fn as_bytestring(&self) -> Option<&Vec<u8>> {
124 match self {
125 ByteStringDatum(bytes) => Some(bytes),
126 _ => None,
127 }
128 }
129}
130
131macro_rules! impl_int_datum_from_uint {
132 ($T:ty) => {
133 impl ToDatum for $T {
134 fn to_datum(&self) -> Datum {
135 Datum::integer(*self)
136 }
137 }
138 };
139}
140
141impl_int_datum_from_uint!(u16);
142impl_int_datum_from_uint!(u32);
143impl_int_datum_from_uint!(u64);
144impl_int_datum_from_uint!(u128);
145
146impl Debug for Datum {
147 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
148 match self {
149 IntegerDatum(i) => write!(f, "I {}", i),
150 ByteStringDatum(bs) => write!(f, "B {}", hex::encode(bs)),
151 ConstructorDatum { constructor, fields } => write!(f, "C {} {:?}", constructor, fields),
152 ListDatum(ds) => write!(f, "L {:?}", ds),
153 MapDatum(map) => {
154 write!(f, "M {:?}", map)
155 },
156 }
157 }
158}
159
160pub fn to_datum_cbor_bytes<T: ToDatum>(msg: T) -> Vec<u8> {
168 minicbor::to_vec(msg.to_datum()).expect("Infallible error type never fails")
169}