Skip to main content

ifx_sdk/
expr.rs

1//! Wire [`Expr`] builders (1:1 with on-chain / `@ifx-run/sdk` `expr`).
2
3use ifx_core::wire::{Expr, Value};
4
5use crate::typed::ScratchValue;
6
7pub fn r(s: &ScratchValue) -> Expr {
8    Expr::Value(Value { index: s.index })
9}
10
11pub fn bool(v: bool) -> Expr {
12    Expr::ConstBool(v)
13}
14
15pub fn u8(v: u8) -> Expr {
16    Expr::ConstU8(v)
17}
18
19pub fn u16(v: u16) -> Expr {
20    Expr::ConstU16(v)
21}
22
23pub fn u32(v: u32) -> Expr {
24    Expr::ConstU32(v)
25}
26
27pub fn u64(v: u64) -> Expr {
28    Expr::ConstU64(v)
29}
30
31pub fn u128(v: u128) -> Expr {
32    Expr::ConstU128(v)
33}
34
35pub fn i8(v: i8) -> Expr {
36    Expr::ConstI8(v)
37}
38
39pub fn i16(v: i16) -> Expr {
40    Expr::ConstI16(v)
41}
42
43pub fn i32(v: i32) -> Expr {
44    Expr::ConstI32(v)
45}
46
47pub fn i64(v: i64) -> Expr {
48    Expr::ConstI64(v)
49}
50
51pub fn i128(v: i128) -> Expr {
52    Expr::ConstI128(v)
53}
54
55pub fn f32(v: f32) -> Expr {
56    Expr::ConstF32(v)
57}
58
59pub fn f64(v: f64) -> Expr {
60    Expr::ConstF64(v)
61}
62
63pub fn pubkey(bytes: [u8; 32]) -> Expr {
64    Expr::ConstPubkey(bytes)
65}
66
67macro_rules! unary {
68    ($fn:ident, $variant:ident) => {
69        pub fn $fn(operand: Expr) -> Expr {
70            Expr::$variant {
71                operand: Box::new(operand),
72            }
73        }
74    };
75}
76
77unary!(not, Not);
78unary!(neg, Neg);
79unary!(is_zero, IsZero);
80unary!(non_zero, NonZero);
81unary!(as_u8, AsU8);
82unary!(as_u16, AsU16);
83unary!(as_u32, AsU32);
84unary!(as_u64, AsU64);
85unary!(as_u128, AsU128);
86unary!(as_i8, AsI8);
87unary!(as_i16, AsI16);
88unary!(as_i32, AsI32);
89unary!(as_i64, AsI64);
90unary!(as_i128, AsI128);
91
92macro_rules! binary {
93    ($fn:ident, $variant:ident) => {
94        pub fn $fn(lhs: Expr, rhs: Expr) -> Expr {
95            Expr::$variant {
96                lhs: Box::new(lhs),
97                rhs: Box::new(rhs),
98            }
99        }
100    };
101}
102
103binary!(add, Add);
104binary!(sub, Sub);
105binary!(mul, Mul);
106binary!(div, Div);
107binary!(div_floor, DivFloor);
108binary!(div_ceil, DivCeil);
109binary!(min, Min);
110binary!(max, Max);
111binary!(eq, Eq);
112binary!(ne, Ne);
113binary!(gt, Gt);
114binary!(ge, Ge);
115binary!(lt, Lt);
116binary!(le, Le);
117binary!(saturating_sub, SaturatingSub);
118binary!(and, And);
119binary!(or, Or);
120
121/// `⌊amount × bps / 10_000⌋` — `amount` is `U64`; `bps` may be `U8`/`U16`/`U32`/`U64`.
122pub fn bps_mul_floor(amount: Expr, bps: Expr) -> Expr {
123    Expr::BpsMulFloor {
124        amount: Box::new(amount),
125        bps: Box::new(bps),
126    }
127}
128
129/// Like [`bps_mul_floor`] with ceiling division.
130pub fn bps_mul_ceil(amount: Expr, bps: Expr) -> Expr {
131    Expr::BpsMulCeil {
132        amount: Box::new(amount),
133        bps: Box::new(bps),
134    }
135}
136
137macro_rules! ternary {
138    ($fn:ident, $variant:ident) => {
139        pub fn $fn(a: Expr, b: Expr, c: Expr) -> Expr {
140            Expr::$variant {
141                a: Box::new(a),
142                b: Box::new(b),
143                c: Box::new(c),
144            }
145        }
146    };
147}
148
149// mul_div_floor: ⌊a × b / c⌋ — a/b are U64 or U128 (same); c same or narrower unsigned.
150ternary!(mul_div_floor, MulDivFloor);
151// mul_div_ceil: like mul_div_floor with ceiling division.
152ternary!(mul_div_ceil, MulDivCeil);
153
154pub fn clamp(value: Expr, lo: Expr, hi: Expr) -> Expr {
155    Expr::Clamp {
156        value: Box::new(value),
157        lo: Box::new(lo),
158        hi: Box::new(hi),
159    }
160}
161
162pub fn select(cond: Expr, then_expr: Expr, else_expr: Expr) -> Expr {
163    Expr::Select {
164        cond: Box::new(cond),
165        then_expr: Box::new(then_expr),
166        else_expr: Box::new(else_expr),
167    }
168}