whisky_common/data/primitives/
tuple.rs1use serde_json::{json, Value};
2
3use crate::{data::{PlutusData, PlutusDataJson}, WError};
4
5#[derive(Clone, Debug, PartialEq)]
6pub struct Tuple<T = PlutusData>
7where
8 T: Clone + PlutusDataJson,
9{
10 pub items: T,
11}
12
13impl<T> Tuple<T>
14where
15 T: Clone + PlutusDataJson,
16{
17 pub fn new(items: T) -> Self {
18 Tuple { items }
19 }
20}
21
22impl<T> PlutusDataJson for Tuple<T>
23where
24 T: Clone + PlutusDataJson,
25{
26 fn to_json(&self) -> Value {
27 let items_json = self.items.to_constr_field();
28 tuple(items_json)
29 }
30
31 fn from_json(value: &Value) -> Result<Self, WError> {
32 let list = value
34 .get("list")
35 .ok_or_else(|| WError::new("Tuple::from_json", "missing 'list' field"))?;
36
37 let items = T::from_json(list)
38 .map_err(WError::add_err_trace("Tuple::from_json"))?;
39
40 Ok(Tuple { items })
41 }
42}
43
44pub fn tuple<T: Into<Value>>(p_tuple: Vec<T>) -> Value {
45 let list: Vec<Value> = p_tuple.into_iter().map(|item| item.into()).collect();
46 json!({ "list": list })
47}
48
49#[macro_export]
50macro_rules! impl_plutus_data_tuple {
51 ( $( $name:ident )+ ) => {
52 #[allow(non_snake_case)]
53 impl<$($name,)+> PlutusDataJson for ($($name,)+)
54 where
55 $($name: PlutusDataJson + Clone,)+
56 {
57 fn to_json(&self) -> Value {
58 json!(self.to_constr_field())
59 }
60 fn to_constr_field(&self) -> Vec<Value> {
61 let ($($name,)+) = self.clone();
62 vec![$($name.to_json(),)+]
63 }
64 fn from_json(value: &Value) -> Result<Self, WError> {
65 let arr = value
66 .as_array()
67 .ok_or_else(|| WError::new("tuple::from_json", "expected array"))?;
68
69 let mut iter = arr.iter();
70 $(
71 let $name = {
72 let item = iter.next()
73 .ok_or_else(|| WError::new("tuple::from_json", "not enough elements"))?;
74 $name::from_json(item)
75 .map_err(WError::add_err_trace("tuple::from_json"))?
76 };
77 )+
78
79 Ok(($($name,)+))
80 }
81 }
82 }
83}
84
85impl_plutus_data_tuple!(T1);
86impl_plutus_data_tuple!(T1 T2);
87impl_plutus_data_tuple!(T1 T2 T3);
88impl_plutus_data_tuple!(T1 T2 T3 T4);
89impl_plutus_data_tuple!(T1 T2 T3 T4 T5);