Skip to main content

amaru_uplc/
data.rs

1use crate::{
2    arena::Arena,
3    binder::Eval,
4    constant::{integer_from, Constant, Integer},
5    flat::Ctx,
6    machine::MachineError,
7};
8
9#[derive(Debug, PartialEq)]
10pub enum PlutusData<'a> {
11    Constr {
12        tag: u64,
13        fields: &'a [&'a PlutusData<'a>],
14    },
15    Map(&'a [(&'a PlutusData<'a>, &'a PlutusData<'a>)]),
16    Integer(&'a Integer),
17    ByteString(&'a [u8]),
18    List(&'a [&'a PlutusData<'a>]),
19}
20
21impl<'a> PlutusData<'a> {
22    pub fn constr(
23        arena: &'a Arena,
24        tag: u64,
25        fields: &'a [&'a PlutusData<'a>],
26    ) -> &'a PlutusData<'a> {
27        arena.alloc(PlutusData::Constr { tag, fields })
28    }
29
30    pub fn list(arena: &'a Arena, items: &'a [&'a PlutusData<'a>]) -> &'a PlutusData<'a> {
31        arena.alloc(PlutusData::List(items))
32    }
33
34    pub fn map(
35        arena: &'a Arena,
36        items: &'a [(&'a PlutusData<'a>, &'a PlutusData<'a>)],
37    ) -> &'a PlutusData<'a> {
38        arena.alloc(PlutusData::Map(items))
39    }
40
41    pub fn integer(arena: &'a Arena, i: &'a Integer) -> &'a PlutusData<'a> {
42        arena.alloc(PlutusData::Integer(i))
43    }
44
45    pub fn integer_from(arena: &'a Arena, i: i128) -> &'a PlutusData<'a> {
46        arena.alloc(PlutusData::Integer(integer_from(arena, i)))
47    }
48
49    pub fn byte_string(arena: &'a Arena, bytes: &'a [u8]) -> &'a PlutusData<'a> {
50        arena.alloc(PlutusData::ByteString(bytes))
51    }
52
53    pub fn from_cbor(
54        arena: &'a Arena,
55        cbor: &'_ [u8],
56    ) -> Result<&'a PlutusData<'a>, minicbor::decode::Error> {
57        minicbor::decode_with(cbor, &mut Ctx { arena })
58    }
59
60    pub fn unwrap_constr<V>(
61        &'a self,
62    ) -> Result<(&'a u64, &'a [&'a PlutusData<'a>]), MachineError<'a, V>>
63    where
64        V: Eval<'a>,
65    {
66        match self {
67            PlutusData::Constr { tag, fields } => Ok((tag, fields)),
68            _ => Err(MachineError::malformed_data(self)),
69        }
70    }
71
72    pub fn unwrap_map<V>(
73        &'a self,
74    ) -> Result<&'a [(&'a PlutusData<'a>, &'a PlutusData<'a>)], MachineError<'a, V>>
75    where
76        V: Eval<'a>,
77    {
78        match self {
79            PlutusData::Map(fields) => Ok(fields),
80            _ => Err(MachineError::malformed_data(self)),
81        }
82    }
83
84    pub fn unwrap_integer<V>(&'a self) -> Result<&'a Integer, MachineError<'a, V>>
85    where
86        V: Eval<'a>,
87    {
88        match self {
89            PlutusData::Integer(i) => Ok(i),
90            _ => Err(MachineError::malformed_data(self)),
91        }
92    }
93
94    pub fn unwrap_byte_string<V>(&'a self) -> Result<&'a [u8], MachineError<'a, V>>
95    where
96        V: Eval<'a>,
97    {
98        match self {
99            PlutusData::ByteString(bytes) => Ok(bytes),
100            _ => Err(MachineError::malformed_data(self)),
101        }
102    }
103
104    pub fn unwrap_list<V>(&'a self) -> Result<&'a [&'a PlutusData<'a>], MachineError<'a, V>>
105    where
106        V: Eval<'a>,
107    {
108        match self {
109            PlutusData::List(items) => Ok(items),
110            _ => Err(MachineError::malformed_data(self)),
111        }
112    }
113
114    pub fn constant(&'a self, arena: &'a Arena) -> &'a Constant<'a> {
115        Constant::data(arena, self)
116    }
117
118    pub fn to_bytes<V>(&'a self, arena: &'a Arena) -> Result<&'a [u8], MachineError<'a, V>>
119    where
120        V: Eval<'a>,
121    {
122        minicbor::to_vec(self)
123            .map(|vec| arena.alloc(vec) as &'a [u8])
124            .map_err(|_| MachineError::serialization_error(self))
125    }
126}