1pub mod loader;
8
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct ANFProgram {
18 #[serde(rename = "contractName")]
19 pub contract_name: String,
20 pub properties: Vec<ANFProperty>,
21 pub methods: Vec<ANFMethod>,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct ANFProperty {
27 pub name: String,
28 #[serde(rename = "type")]
29 pub prop_type: String,
30 pub readonly: bool,
31 #[serde(rename = "initialValue", skip_serializing_if = "Option::is_none")]
32 pub initial_value: Option<serde_json::Value>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct ANFMethod {
38 pub name: String,
39 pub params: Vec<ANFParam>,
40 pub body: Vec<ANFBinding>,
41 #[serde(rename = "isPublic")]
42 pub is_public: bool,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct ANFParam {
48 pub name: String,
49 #[serde(rename = "type")]
50 pub param_type: String,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct ANFBinding {
60 pub name: String,
61 pub value: ANFValue,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
72#[serde(tag = "kind")]
73pub enum ANFValue {
74 #[serde(rename = "load_param")]
75 LoadParam { name: String },
76
77 #[serde(rename = "load_prop")]
78 LoadProp { name: String },
79
80 #[serde(rename = "load_const")]
81 LoadConst { value: serde_json::Value },
82
83 #[serde(rename = "bin_op")]
84 BinOp {
85 op: String,
86 left: String,
87 right: String,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 result_type: Option<String>,
90 },
91
92 #[serde(rename = "unary_op")]
93 UnaryOp {
94 op: String,
95 operand: String,
96 #[serde(skip_serializing_if = "Option::is_none")]
97 result_type: Option<String>,
98 },
99
100 #[serde(rename = "call")]
101 Call {
102 func: String,
103 args: Vec<String>,
104 },
105
106 #[serde(rename = "method_call")]
107 MethodCall {
108 object: String,
109 method: String,
110 args: Vec<String>,
111 },
112
113 #[serde(rename = "if")]
114 If {
115 cond: String,
116 then: Vec<ANFBinding>,
117 #[serde(rename = "else")]
118 else_branch: Vec<ANFBinding>,
119 },
120
121 #[serde(rename = "loop")]
122 Loop {
123 count: usize,
124 body: Vec<ANFBinding>,
125 #[serde(rename = "iterVar")]
126 iter_var: String,
127 },
128
129 #[serde(rename = "assert")]
130 Assert { value: String },
131
132 #[serde(rename = "update_prop")]
133 UpdateProp { name: String, value: String },
134
135 #[serde(rename = "get_state_script")]
136 GetStateScript {},
137
138 #[serde(rename = "check_preimage")]
139 CheckPreimage { preimage: String },
140
141 #[serde(rename = "deserialize_state")]
142 DeserializeState { preimage: String },
143
144 #[serde(rename = "add_output")]
145 AddOutput {
146 satoshis: String,
147 #[serde(rename = "stateValues")]
148 state_values: Vec<String>,
149 #[serde(default)]
150 preimage: String,
151 },
152
153 #[serde(rename = "add_raw_output")]
154 AddRawOutput {
155 satoshis: String,
156 #[serde(rename = "scriptBytes")]
157 script_bytes: String,
158 },
159
160 #[serde(rename = "array_literal")]
161 ArrayLiteral {
162 elements: Vec<String>,
163 },
164}
165
166#[derive(Debug, Clone)]
172pub enum ConstValue {
173 Bool(bool),
174 Int(i128),
175 Str(String),
176}
177
178impl ANFValue {
179 pub fn const_value(&self) -> Option<ConstValue> {
181 match self {
182 ANFValue::LoadConst { value } => parse_const_value(value),
183 _ => None,
184 }
185 }
186}
187
188pub fn parse_const_value(v: &serde_json::Value) -> Option<ConstValue> {
190 match v {
191 serde_json::Value::Bool(b) => Some(ConstValue::Bool(*b)),
192 serde_json::Value::Number(n) => {
193 if let Some(i) = n.as_i64() {
195 Some(ConstValue::Int(i as i128))
196 } else if let Some(f) = n.as_f64() {
197 Some(ConstValue::Int(f as i128))
198 } else {
199 None
200 }
201 }
202 serde_json::Value::String(s) => Some(ConstValue::Str(s.clone())),
203 _ => None,
204 }
205}