Skip to main content

amaru_uplc/
constant.rs

1use crate::{
2    arena::Arena, binder::Eval, data::PlutusData, ledger_value::LedgerValue, machine::MachineError,
3    typ::Type,
4};
5
6#[derive(Debug, PartialEq)]
7pub enum Constant<'a> {
8    Integer(&'a Integer),
9    ByteString(&'a [u8]),
10    String(&'a str),
11    Boolean(bool),
12    Data(&'a PlutusData<'a>),
13    ProtoList(&'a Type<'a>, &'a [&'a Constant<'a>]),
14    ProtoArray(&'a Type<'a>, &'a [&'a Constant<'a>]),
15    ProtoPair(
16        &'a Type<'a>,
17        &'a Type<'a>,
18        &'a Constant<'a>,
19        &'a Constant<'a>,
20    ),
21    Unit,
22    Bls12_381G1Element(&'a blst::blst_p1),
23    Bls12_381G2Element(&'a blst::blst_p2),
24    Bls12_381MlResult(&'a blst::blst_fp12),
25    Value(&'a LedgerValue<'a>),
26}
27
28pub type Integer = num::BigInt;
29
30pub fn integer(arena: &Arena) -> &Integer {
31    arena.alloc_integer(Integer::default())
32}
33
34pub fn integer_from(arena: &Arena, i: i128) -> &Integer {
35    arena.alloc_integer(Integer::from(i))
36}
37
38impl<'a> Constant<'a> {
39    pub fn integer(arena: &'a Arena, i: &'a Integer) -> &'a Constant<'a> {
40        arena.alloc(Constant::Integer(i))
41    }
42
43    pub fn integer_from(arena: &'a Arena, i: i128) -> &'a Constant<'a> {
44        arena.alloc(Constant::Integer(integer_from(arena, i)))
45    }
46
47    pub fn byte_string(arena: &'a Arena, bytes: &'a [u8]) -> &'a Constant<'a> {
48        arena.alloc(Constant::ByteString(bytes))
49    }
50
51    pub fn string(arena: &'a Arena, s: &'a str) -> &'a Constant<'a> {
52        arena.alloc(Constant::String(s))
53    }
54
55    pub fn bool(arena: &'a Arena, v: bool) -> &'a Constant<'a> {
56        arena.alloc(Constant::Boolean(v))
57    }
58
59    pub fn data(arena: &'a Arena, d: &'a PlutusData<'a>) -> &'a Constant<'a> {
60        arena.alloc(Constant::Data(d))
61    }
62
63    pub fn unit(arena: &'a Arena) -> &'a Constant<'a> {
64        arena.alloc(Constant::Unit)
65    }
66
67    pub fn proto_list(
68        arena: &'a Arena,
69        inner: &'a Type<'a>,
70        values: &'a [&'a Constant<'a>],
71    ) -> &'a Constant<'a> {
72        arena.alloc(Constant::ProtoList(inner, values))
73    }
74
75    pub fn proto_array(
76        arena: &'a Arena,
77        inner: &'a Type<'a>,
78        values: &'a [&'a Constant<'a>],
79    ) -> &'a Constant<'a> {
80        arena.alloc(Constant::ProtoArray(inner, values))
81    }
82
83    pub fn proto_pair(
84        arena: &'a Arena,
85        first_type: &'a Type<'a>,
86        second_type: &'a Type<'a>,
87        first_value: &'a Constant<'a>,
88        second_value: &'a Constant<'a>,
89    ) -> &'a Constant<'a> {
90        arena.alloc(Constant::ProtoPair(
91            first_type,
92            second_type,
93            first_value,
94            second_value,
95        ))
96    }
97
98    pub fn g1(arena: &'a Arena, g1: &'a blst::blst_p1) -> &'a Constant<'a> {
99        arena.alloc(Constant::Bls12_381G1Element(g1))
100    }
101
102    pub fn g2(arena: &'a Arena, g2: &'a blst::blst_p2) -> &'a Constant<'a> {
103        arena.alloc(Constant::Bls12_381G2Element(g2))
104    }
105
106    pub fn ml_result(arena: &'a Arena, ml_res: &'a blst::blst_fp12) -> &'a Constant<'a> {
107        arena.alloc(Constant::Bls12_381MlResult(ml_res))
108    }
109
110    pub fn ledger_value(arena: &'a Arena, v: &'a LedgerValue<'a>) -> &'a Constant<'a> {
111        arena.alloc(Constant::Value(v))
112    }
113
114    pub fn unwrap_data<V>(&'a self) -> Result<&'a PlutusData<'a>, MachineError<'a, V>>
115    where
116        V: Eval<'a>,
117    {
118        match self {
119            Constant::Data(data) => Ok(data),
120            _ => Err(MachineError::not_data(self)),
121        }
122    }
123
124    pub fn type_of(&self, arena: &'a Arena) -> &'a Type<'a> {
125        match self {
126            Constant::Integer(_) => Type::integer(arena),
127            Constant::ByteString(_) => Type::byte_string(arena),
128            Constant::String(_) => Type::string(arena),
129            Constant::Boolean(_) => Type::bool(arena),
130            Constant::Data(_) => Type::data(arena),
131            Constant::ProtoList(t, _) => Type::list(arena, t),
132            Constant::ProtoArray(t, _) => Type::array(arena, t),
133            Constant::ProtoPair(t1, t2, _, _) => Type::pair(arena, t1, t2),
134            Constant::Unit => Type::unit(arena),
135            Constant::Bls12_381G1Element(_) => Type::g1(arena),
136            Constant::Bls12_381G2Element(_) => Type::g2(arena),
137            Constant::Bls12_381MlResult(_) => Type::ml_result(arena),
138            Constant::Value(_) => Type::value(arena),
139        }
140    }
141}