cardano_sdk/chain/
common.rs

1use cbored::{Decode, DecodeError, DecodeErrorKind, Encode, Reader, Writer};
2use std::fmt;
3
4/// Identical to Vec<u8> with a CBOR serializer/deserializer and an hexadecimal pretty-printer
5#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
6pub struct Bytes(pub Vec<u8>);
7
8impl AsRef<[u8]> for Bytes {
9    fn as_ref(&self) -> &[u8] {
10        &self.0
11    }
12}
13
14impl fmt::Debug for Bytes {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        write!(f, "{}", hex::encode(&self.0))
17    }
18}
19
20impl fmt::Display for Bytes {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        write!(f, "{}", hex::encode(&self.0))
23    }
24}
25
26impl Decode for Bytes {
27    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
28        Ok(Bytes(reader.decode()?))
29    }
30}
31
32impl Encode for Bytes {
33    fn encode(&self, writer: &mut Writer) {
34        writer.encode(self.as_ref())
35    }
36}
37
38/// Nullable object in CBOR serialization, isomorphic to rust's `Option<T>`
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub enum Nullable<T> {
41    Null,
42    Some(T),
43}
44
45impl<T> Nullable<T> {
46    pub fn option(self) -> Option<T> {
47        match self {
48            Nullable::Null => None,
49            Nullable::Some(t) => Some(t),
50        }
51    }
52
53    pub fn option_ref(&self) -> Option<&T> {
54        match self {
55            Nullable::Null => None,
56            Nullable::Some(t) => Some(t),
57        }
58    }
59}
60
61impl<T> From<Option<T>> for Nullable<T> {
62    fn from(o: Option<T>) -> Self {
63        match o {
64            None => Nullable::Null,
65            Some(o) => Nullable::Some(o),
66        }
67    }
68}
69
70impl<T: Decode> Decode for Nullable<T> {
71    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
72        let ty = reader
73            .peek_type()
74            .map_err(DecodeErrorKind::ReaderError)
75            .map_err(|e| e.context::<Self>())?;
76
77        if ty == cbored::Type::Null {
78            reader
79                .null()
80                .map_err(DecodeErrorKind::ReaderError)
81                .map_err(|e| e.context::<Self>())?;
82            Ok(Nullable::Null)
83        } else {
84            Ok(Nullable::Some(
85                reader.decode().map_err(|e| e.push::<Self>())?,
86            ))
87        }
88    }
89}
90
91impl<T: Encode> Encode for Nullable<T> {
92    fn encode(&self, writer: &mut Writer) {
93        match self {
94            Nullable::Null => writer.constant(cbored::Constant::Null),
95            Nullable::Some(t) => writer.encode(t),
96        }
97    }
98}
99
100#[macro_export]
101macro_rules! vec_structure {
102    ($name:ident, $content:path) => {
103        crate::vec_structure!($name, $content, []);
104    };
105    ($name:ident, $content:path, [ $($derive_ident:ident)* ]) => {
106        #[derive(Clone, Debug, PartialEq, Eq, $($derive_ident),*)]
107        pub struct $name(Vec<$content>);
108
109        impl AsRef<[$content]> for $name {
110            fn as_ref(&self) -> &[$content] {
111                &self.0
112            }
113        }
114
115        impl From<Vec<$content>> for $name {
116            fn from(v: Vec<$content>) -> Self {
117                Self(v)
118            }
119        }
120
121        impl $name {
122            pub fn len(&self) -> usize {
123                self.0.len()
124            }
125
126            pub fn new() -> Self {
127                Self(Vec::new())
128            }
129
130            pub fn iter(&self) -> impl Iterator<Item = &$content> {
131                self.0.iter()
132            }
133
134            pub fn push(&mut self, t: $content) {
135                self.0.push(t)
136            }
137        }
138
139        impl ::cbored::Encode for $name {
140            fn encode(&self, writer: &mut ::cbored::Writer) {
141                let len = ::cbored::StructureLength::from(self.0.len() as u64);
142                writer.array_build(len, |writer| {
143                    for v in self.0.iter() {
144                        writer.encode(v);
145                    }
146                })
147            }
148        }
149
150        impl ::cbored::Decode for $name {
151            fn decode<'a>(
152                reader: &mut ::cbored::Reader<'a>,
153            ) -> Result<Self, ::cbored::DecodeError> {
154                let array = reader
155                    .array()
156                    .map_err(::cbored::DecodeErrorKind::ReaderError)
157                    .map_err(|e| e.context::<Self>())?;
158                let out = array
159                    .iter()
160                    .map(|mut r| r.decode::<$content>())
161                    .collect::<Result<Vec<_>, ::cbored::DecodeError>>()
162                    .map_err(|e| e.push::<Self>())?;
163                Ok($name(out))
164            }
165        }
166    };
167}
168
169#[macro_export]
170macro_rules! vec_indef_structure {
171    ($name:ident, $content:path) => {
172        #[derive(Clone, Debug, PartialEq, Eq)]
173        pub struct $name(Vec<$content>);
174
175        impl AsRef<[$content]> for $name {
176            fn as_ref(&self) -> &[$content] {
177                &self.0
178            }
179        }
180
181        impl From<Vec<$content>> for $name {
182            fn from(v: Vec<$content>) -> Self {
183                Self(v)
184            }
185        }
186
187        impl $name {
188            #[allow(dead_code)]
189            pub fn len(&self) -> usize {
190                self.0.len()
191            }
192
193            #[allow(dead_code)]
194            pub fn new() -> Self {
195                Self(Vec::new())
196            }
197
198            #[allow(dead_code)]
199            pub fn iter(&self) -> impl Iterator<Item = &$content> {
200                self.0.iter()
201            }
202        }
203
204        impl ::cbored::Encode for $name {
205            fn encode(&self, writer: &mut ::cbored::Writer) {
206                let len = ::cbored::StructureLength::Indefinite;
207                writer.array_build(len, |writer| {
208                    for v in self.0.iter() {
209                        writer.encode(v);
210                    }
211                })
212            }
213        }
214
215        impl ::cbored::Decode for $name {
216            fn decode<'a>(
217                reader: &mut ::cbored::Reader<'a>,
218            ) -> Result<Self, ::cbored::DecodeError> {
219                let array = reader
220                    .array()
221                    .map_err(DecodeErrorKind::ReaderError)
222                    .map_err(|e| e.context::<Self>())?;
223                let out = array
224                    .iter()
225                    .map(|mut r| r.decode::<$content>())
226                    .collect::<Result<Vec<_>, ::cbored::DecodeError>>()
227                    .map_err(|e| e.push::<Self>())?;
228                Ok($name(out))
229            }
230        }
231    };
232}
233
234#[macro_export]
235macro_rules! map_structure {
236    ($name:ident, $key:ident, $content:ident) => {
237        crate::map_structure!($name, $key, $content, []);
238    };
239    ($name:ident, $key:ident, $content:ident, [ $($derive_ident:ident)* ]) => {
240        #[derive(Clone, Debug, PartialEq, Eq, $($derive_ident),* )]
241        pub struct $name(Vec<($key, $content)>);
242
243        impl From<Vec<($key, $content)>> for $name {
244            fn from(v: Vec<($key, $content)>) -> Self {
245                Self(v.into_iter().collect())
246            }
247        }
248
249        impl From<std::collections::BTreeMap<$key, $content>> for $name {
250            fn from(v: std::collections::BTreeMap<$key, $content>) -> Self {
251                Self(v.into_iter().collect())
252            }
253        }
254
255        impl $name {
256            #[allow(dead_code)]
257            pub fn new() -> Self {
258                Self(vec![])
259            }
260
261            #[allow(dead_code)]
262            pub fn add(&mut self, key: $key, content: $content) {
263                self.0.push((key, content))
264            }
265
266            #[allow(dead_code)]
267            pub fn iter(&self) -> impl Iterator<Item = &($key, $content)> {
268                self.0.iter()
269            }
270        }
271
272        impl ::cbored::Encode for $name {
273            fn encode(&self, writer: &mut ::cbored::Writer) {
274                let len = ::cbored::StructureLength::from(self.0.len() as u64);
275                writer.map_build(len, |writer| {
276                    for (k, v) in self.0.iter() {
277                        writer.encode(k);
278                        writer.encode(v);
279                    }
280                })
281            }
282        }
283
284        impl ::cbored::Decode for $name {
285            fn decode<'a>(
286                reader: &mut ::cbored::Reader<'a>,
287            ) -> Result<Self, ::cbored::DecodeError> {
288                let map = reader.map().map_err(::cbored::DecodeErrorKind::ReaderError).map_err(|e| e.context::<Self>())?;
289                let out = map
290                    .iter()
291                    .map(|(mut k, mut v)| {
292                        let key = k.decode().map_err(|e| e.push_str("key").push::<Self>())?;
293                        let value = v.decode().map_err(|e| e.push_str("val").push::<Self>())?;
294                        Ok((key, value))
295                    })
296                    .collect::<Result<Vec<($key, $content)>, ::cbored::DecodeError>>()?;
297                Ok($name(out))
298            }
299        }
300    };
301}
302
303#[derive(Clone, Debug, PartialEq, Eq)]
304pub struct AnyCbor(pub cbored::DataOwned);
305
306impl ::cbored::Encode for AnyCbor {
307    fn encode(&self, writer: &mut ::cbored::Writer) {
308        writer.encode(&self.0)
309    }
310}
311
312impl ::cbored::Decode for AnyCbor {
313    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
314        reader.decode().map(AnyCbor)
315    }
316}
317
318/// CBOR Negative u64
319#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
320#[allow(non_camel_case_types)]
321pub struct n64(pub u64);
322
323impl Decode for n64 {
324    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
325        let neg: cbored::Negative = reader
326            .negative()
327            .map_err(::cbored::DecodeErrorKind::ReaderError)
328            .map_err(|e| e.context::<Self>())?;
329        Ok(n64(neg.negative_u64()))
330    }
331}
332
333impl Encode for n64 {
334    fn encode(&self, writer: &mut Writer) {
335        writer.negative(::cbored::Negative::canonical(self.0))
336    }
337}
338
339crate::vec_structure!(Numbers64, Number64);
340
341/// CBOR Number Positive or Negative
342#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
343#[allow(non_camel_case_types)]
344pub struct Number64(pub i128);
345
346impl Decode for Number64 {
347    fn decode<'a>(reader: &mut Reader<'a>) -> Result<Self, DecodeError> {
348        match cbored::Scalar::decode(reader)? {
349            cbored::Scalar::Positive(v) => Ok(Number64(v.to_u64() as i128)),
350            cbored::Scalar::Negative(v) => Ok(Number64(1 - (v.negative_u64() as i128))),
351        }
352    }
353}
354
355impl Encode for Number64 {
356    fn encode(&self, writer: &mut Writer) {
357        if self.0 >= 0 {
358            writer.positive(cbored::Positive::canonical(self.0 as u64))
359        } else {
360            writer.negative(cbored::Negative::canonical(-(1 + self.0) as u64))
361        }
362    }
363}