1use std::collections::{HashMap, HashSet};
12
13use bincode::{Decode, Encode};
14use serde::{Deserialize, Serialize};
15
16use crate::{Utxo, UtxoRef};
17
18pub const IR_VERSION: &str = "v1alpha7";
19
20#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
21pub struct StructExpr {
22 pub constructor: usize,
23 pub fields: Vec<Expression>,
24}
25
26impl StructExpr {
27 pub fn unit() -> Self {
28 Self {
29 constructor: 0,
30 fields: vec![],
31 }
32 }
33}
34
35#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
36pub enum Coerce {
37 NoOp(Expression),
38 IntoAssets(Expression),
39 IntoDatum(Expression),
40 IntoScript(Expression),
41}
42
43pub type PropertyIndex = usize;
44
45#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
54pub enum BuiltInOp {
55 NoOp(Expression),
56 Add(Expression, Expression),
57 Sub(Expression, Expression),
58 Negate(Expression),
59 Property(Expression, PropertyIndex),
60}
61
62#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
71pub enum CompilerOp {
72 BuildScriptAddress(Expression),
73}
74
75#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
76pub struct AssetExpr {
77 pub policy: Expression,
78 pub asset_name: Expression,
79 pub amount: Expression,
80}
81
82#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
89pub struct AdHocDirective {
90 pub name: String,
91 pub data: HashMap<String, Expression>,
92}
93
94#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
95pub enum ScriptSource {
96 Embedded(Expression),
97 UtxoRef {
98 r#ref: Expression,
99 source: Option<Expression>,
100 },
101}
102
103impl ScriptSource {
104 pub fn new_ref(r#ref: Expression, source: Expression) -> Self {
105 Self::UtxoRef {
106 r#ref,
107 source: Some(source),
108 }
109 }
110
111 pub fn new_embedded(source: Expression) -> Self {
112 Self::Embedded(source)
113 }
114
115 pub fn expect_parameter(policy_name: String) -> Self {
116 Self::Embedded(
117 Param::ExpectValue(
118 format!("{}_script", policy_name.to_lowercase()),
119 Type::Bytes,
120 )
121 .into(),
122 )
123 }
124
125 pub fn expect_ref_input(policy_name: String, r#ref: Expression) -> Self {
126 Self::UtxoRef {
127 r#ref: r#ref.clone(),
128 source: Some(
129 Coerce::IntoScript(
130 Param::ExpectInput(
131 format!("{}_script", policy_name.to_lowercase()),
132 InputQuery {
133 address: Expression::None,
134 min_amount: Expression::None,
135 r#ref,
136 },
137 )
138 .into(),
139 )
140 .into(),
141 ),
142 }
143 }
144
145 pub fn as_utxo_ref(&self) -> Option<Expression> {
146 match self {
147 Self::UtxoRef { r#ref, .. } => Some(r#ref.clone()),
148 Self::Embedded(Expression::UtxoRefs(x)) => Some(Expression::UtxoRefs(x.clone())),
149 _ => None,
150 }
151 }
152}
153
154#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
155pub struct PolicyExpr {
156 pub name: String,
157 pub hash: Expression,
158 pub script: ScriptSource,
159}
160
161#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
162pub enum Type {
163 Undefined,
164 Unit,
165 Int,
166 Bool,
167 Bytes,
168 Address,
169 Utxo,
170 UtxoRef,
171 AnyAsset,
172 List,
173 Custom(String),
174}
175
176#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
177pub enum Param {
178 Set(Expression),
179 ExpectValue(String, Type),
180 ExpectInput(String, InputQuery),
181 ExpectFees,
182}
183
184#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
185pub enum Expression {
186 None,
187 List(Vec<Expression>),
188 Tuple(Box<(Expression, Expression)>),
189 Struct(StructExpr),
190 Bytes(Vec<u8>),
191 Number(i128),
192 Bool(bool),
193 String(String),
194 Address(Vec<u8>),
195 Hash(Vec<u8>),
196 UtxoRefs(Vec<UtxoRef>),
197 UtxoSet(HashSet<Utxo>),
198 Assets(Vec<AssetExpr>),
199
200 EvalParam(Box<Param>),
201 EvalBuiltIn(Box<BuiltInOp>),
202 EvalCompiler(Box<CompilerOp>),
203 EvalCoerce(Box<Coerce>),
204
205 AdHocDirective(Box<AdHocDirective>),
207}
208
209impl Default for Expression {
210 fn default() -> Self {
211 Self::None
212 }
213}
214
215impl Expression {
216 pub fn is_none(&self) -> bool {
217 matches!(self, Self::None)
218 }
219
220 pub fn as_option(&self) -> Option<&Self> {
221 match self {
222 Self::None => None,
223 _ => Some(self),
224 }
225 }
226}
227
228impl From<BuiltInOp> for Expression {
229 fn from(op: BuiltInOp) -> Self {
230 Self::EvalBuiltIn(Box::new(op))
231 }
232}
233
234impl From<CompilerOp> for Expression {
235 fn from(op: CompilerOp) -> Self {
236 Self::EvalCompiler(Box::new(op))
237 }
238}
239
240impl From<Coerce> for Expression {
241 fn from(coerce: Coerce) -> Self {
242 Self::EvalCoerce(Box::new(coerce))
243 }
244}
245
246impl From<Param> for Expression {
247 fn from(param: Param) -> Self {
248 Self::EvalParam(Box::new(param))
249 }
250}
251
252#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
253pub struct InputQuery {
254 pub address: Expression,
255 pub min_amount: Expression,
256 pub r#ref: Expression,
257}
258
259#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
260pub struct Input {
261 pub name: String,
262 pub utxos: Expression,
263 pub redeemer: Expression,
264}
265
266#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone)]
267pub struct Output {
268 pub address: Expression,
269 pub datum: Expression,
270 pub amount: Expression,
271}
272
273#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone)]
274pub struct Validity {
275 pub since: Expression,
276 pub until: Expression,
277}
278
279#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone)]
280pub struct Mint {
281 pub amount: Expression,
282 pub redeemer: Expression,
283}
284
285#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone)]
286pub struct Collateral {
287 pub utxos: Expression,
288}
289
290#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone)]
291pub struct Metadata {
292 pub key: Expression,
293 pub value: Expression,
294}
295
296#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone)]
297pub struct Signers {
298 pub signers: Vec<Expression>,
299}
300
301#[derive(Encode, Decode, Serialize, Deserialize, Debug, Clone)]
302pub struct Tx {
303 pub fees: Expression,
304 pub references: Vec<Expression>,
305 pub inputs: Vec<Input>,
306 pub outputs: Vec<Output>,
307 pub validity: Option<Validity>,
308 pub mints: Vec<Mint>,
309 pub adhoc: Vec<AdHocDirective>,
310 pub collateral: Vec<Collateral>,
311 pub signers: Option<Signers>,
312 pub metadata: Vec<Metadata>,
313}