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);
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);