whisky_common/data/primitives/
constructors.rs

1use serde_json::{json, Value};
2
3use crate::data::PlutusDataJson;
4
5#[derive(Clone, Debug)]
6pub struct Constr<T = ()>
7where
8    T: Clone + PlutusDataJson,
9{
10    pub tag: u64,
11    pub fields: T,
12}
13
14impl<T> Constr<T>
15where
16    T: Clone + PlutusDataJson,
17{
18    pub fn new(tag: u64, fields: T) -> Self {
19        Constr {
20            tag,
21            fields: fields,
22        }
23    }
24}
25
26impl<T> PlutusDataJson for Constr<T>
27where
28    T: Clone + PlutusDataJson,
29{
30    fn to_json(&self) -> Value {
31        let fields_json = self.fields.to_constr_field();
32        constr(self.tag, fields_json)
33    }
34}
35
36impl PlutusDataJson for () {
37    fn to_json(&self) -> Value {
38        json!([])
39    }
40    fn to_constr_field(&self) -> Vec<serde_json::Value> {
41        vec![]
42    }
43}
44
45// value constructor
46
47pub fn constr<N: Into<Value>, T: Into<Value>>(constructor: N, fields: T) -> Value {
48    json!({ "constructor": constructor.into(), "fields": fields.into() })
49}
50
51pub fn constr0<T: Into<Value>>(fields: T) -> Value {
52    constr(0, fields)
53}
54
55pub fn constr1<T: Into<Value>>(fields: T) -> Value {
56    constr(1, fields)
57}
58
59pub fn constr2<T: Into<Value>>(fields: T) -> Value {
60    constr(2, fields)
61}
62
63/// Deprecated: Use `constr` instead.
64pub fn con_str<N: Into<Value>, T: Into<Value>>(constructor: N, fields: T) -> Value {
65    json!({ "constructor": constructor.into(), "fields": fields.into() })
66}
67
68/// Deprecated: Use `constr0` instead.
69pub fn con_str0<T: Into<Value>>(fields: T) -> Value {
70    con_str(0, fields)
71}
72
73/// Deprecated: Use `constr1` instead.
74pub fn con_str1<T: Into<Value>>(fields: T) -> Value {
75    con_str(1, fields)
76}
77
78/// Deprecated: Use `constr2` instead.
79pub fn con_str2<T: Into<Value>>(fields: T) -> Value {
80    con_str(2, fields)
81}
82
83#[macro_export]
84macro_rules! impl_constr_fields {
85    ( $( $name:ident )+ ) => {
86        #[allow(non_snake_case)]
87        impl<$($name,)+> PlutusDataJson for Box<($($name,)+)>
88        where
89            $($name: PlutusDataJson + Clone,)+
90        {
91            fn to_json(&self) -> Value {
92                json!(self.to_constr_field())
93            }
94
95            fn to_constr_field(&self) -> Vec<Value> {
96                let tuple = &**self;
97                let ($($name,)+) = tuple.clone();
98                vec![$($name.to_json(),)+]
99            }
100        }
101    }
102}
103
104impl_constr_fields!(T1 T2);
105impl_constr_fields!(T1 T2 T3);
106impl_constr_fields!(T1 T2 T3 T4);
107impl_constr_fields!(T1 T2 T3 T4 T5);
108impl_constr_fields!(T1 T2 T3 T4 T5 T6);
109impl_constr_fields!(T1 T2 T3 T4 T5 T6 T7);
110impl_constr_fields!(T1 T2 T3 T4 T5 T6 T7 T8);
111impl_constr_fields!(T1 T2 T3 T4 T5 T6 T7 T8 T9);
112impl_constr_fields!(T1 T2 T3 T4 T5 T6 T7 T8 T9 T10);
113
114#[macro_export]
115macro_rules! impl_constr_n {
116    ($($name:ident: $tag:expr),+) => {
117        $(
118            #[derive(Clone, Debug)]
119            pub struct $name<T = ()>
120            where
121                T: Clone + PlutusDataJson + ,
122            {
123                pub fields: T,
124            }
125
126            impl<T> $name<T>
127            where
128                T: Clone + PlutusDataJson + ,
129            {
130                pub fn new(fields: T) -> Self {
131                    $name {
132                        fields,
133                    }
134                }
135            }
136
137            impl<T> PlutusDataJson for $name<T>
138            where
139                T: Clone + PlutusDataJson + ,
140            {
141                fn to_json(&self) -> Value {
142                    let fields_json = self.fields.to_constr_field();
143                    constr($tag, fields_json)
144                }
145            }
146        )+
147    }
148}
149
150impl_constr_n!(
151    Constr0: 0,
152    Constr1: 1,
153    Constr2: 2,
154    Constr3: 3
155);