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}