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}