whisky_common/data/primitives/
constructors.rs1use 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
45pub 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
63pub fn con_str<N: Into<Value>, T: Into<Value>>(constructor: N, fields: T) -> Value {
65 json!({ "constructor": constructor.into(), "fields": fields.into() })
66}
67
68pub fn con_str0<T: Into<Value>>(fields: T) -> Value {
70 con_str(0, fields)
71}
72
73pub fn con_str1<T: Into<Value>>(fields: T) -> Value {
75 con_str(1, fields)
76}
77
78pub 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);
113impl_constr_fields!(T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11);
114impl_constr_fields!(T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12);
115
116#[macro_export]
117macro_rules! impl_constr_n {
118 ($($name:ident: $tag:expr),+) => {
119 $(
120 #[derive(Clone, Debug)]
121 pub struct $name<T = ()>
122 where
123 T: Clone + PlutusDataJson + ,
124 {
125 pub fields: T,
126 }
127
128 impl<T> $name<T>
129 where
130 T: Clone + PlutusDataJson + ,
131 {
132 pub fn new(fields: T) -> Self {
133 $name {
134 fields,
135 }
136 }
137 }
138
139 impl<T> PlutusDataJson for $name<T>
140 where
141 T: Clone + PlutusDataJson + ,
142 {
143 fn to_json(&self) -> Value {
144 let fields_json = self.fields.to_constr_field();
145 constr($tag, fields_json)
146 }
147 }
148 )+
149 }
150}
151
152impl_constr_n!(
153 Constr0: 0,
154 Constr1: 1,
155 Constr2: 2,
156 Constr3: 3
157);