Skip to main content

amaru_uplc/
constant.rs

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