tezos_smart_rollup_encoding/
michelson.rs1use nom::branch::alt;
7use nom::combinator::map;
8use std::fmt::Debug;
9use tezos_data_encoding::enc::{self, BinResult, BinWriter};
10use tezos_data_encoding::encoding::{Encoding, HasEncoding};
11use tezos_data_encoding::nom::{self as nom_read, NomReader, NomResult};
12use tezos_data_encoding::types::Zarith;
13
14mod micheline;
15#[cfg(feature = "alloc")]
16pub mod ticket;
17
18use super::contract::Contract;
19use micheline::{
20 bin_write_micheline_bytes, bin_write_micheline_int, bin_write_micheline_string,
21 bin_write_prim_1_arg_no_annots, bin_write_prim_2_args_no_annots,
22 bin_write_prim_no_args_no_annots, nom_read_micheline_bytes, nom_read_micheline_int,
23 nom_read_micheline_string, MichelinePrim1ArgNoAnnots, MichelinePrim2ArgsNoAnnots,
24 MichelinePrimNoArgsNoAnnots,
25};
26use v1_primitives as prim;
27
28pub mod v1_primitives {
29 pub const LEFT_TAG: u8 = 5;
35
36 pub const NONE_TAG: u8 = 6;
38
39 pub const PAIR_TAG: u8 = 7;
41
42 pub const RIGHT_TAG: u8 = 8;
44
45 pub const SOME_TAG: u8 = 9;
47
48 pub const UNIT_TAG: u8 = 11;
50}
51
52pub trait Michelson:
54 HasEncoding + BinWriter + NomReader + Debug + PartialEq + Eq
55{
56}
57
58impl Michelson for MichelsonUnit {}
59impl Michelson for MichelsonContract {}
60impl Michelson for MichelsonInt {}
61impl Michelson for MichelsonString {}
62impl Michelson for MichelsonBytes {}
63impl<Arg0, Arg1> Michelson for MichelsonPair<Arg0, Arg1>
64where
65 Arg0: Michelson,
66 Arg1: Michelson,
67{
68}
69impl<Arg0, Arg1> Michelson for MichelsonOr<Arg0, Arg1>
70where
71 Arg0: Michelson,
72 Arg1: Michelson,
73{
74}
75impl<Arg> Michelson for MichelsonOption<Arg> where Arg: Michelson {}
76
77#[derive(Debug, PartialEq, Eq)]
79pub struct MichelsonUnit;
80
81#[derive(Debug, PartialEq, Eq)]
84pub struct MichelsonContract(pub Contract);
85
86#[derive(Debug, PartialEq, Eq)]
88pub struct MichelsonPair<Arg0, Arg1>(pub Arg0, pub Arg1)
89where
90 Arg0: Debug + PartialEq + Eq,
91 Arg1: Debug + PartialEq + Eq;
92
93#[derive(Debug, PartialEq, Eq)]
95pub enum MichelsonOr<Arg0, Arg1>
96where
97 Arg0: Debug + PartialEq + Eq,
98 Arg1: Debug + PartialEq + Eq,
99{
100 Left(Arg0),
102 Right(Arg1),
104}
105
106#[derive(Debug, PartialEq, Eq)]
108pub struct MichelsonOption<Arg>(pub Option<Arg>)
109where
110 Arg: Debug + PartialEq + Eq;
111
112#[derive(Debug, PartialEq, Eq)]
114pub struct MichelsonString(pub String);
115
116#[derive(Debug, PartialEq, Eq)]
118pub struct MichelsonBytes(pub Vec<u8>);
119
120#[derive(Debug, PartialEq, Eq)]
122pub struct MichelsonInt(pub Zarith);
123
124impl From<String> for MichelsonString {
128 fn from(str: String) -> MichelsonString {
129 MichelsonString(str)
130 }
131}
132
133impl From<Vec<u8>> for MichelsonBytes {
134 fn from(b: Vec<u8>) -> MichelsonBytes {
135 MichelsonBytes(b)
136 }
137}
138
139impl From<Zarith> for MichelsonInt {
140 fn from(value: Zarith) -> MichelsonInt {
141 MichelsonInt(value)
142 }
143}
144
145impl From<i32> for MichelsonInt {
146 fn from(value: i32) -> MichelsonInt {
147 MichelsonInt(Zarith(value.into()))
148 }
149}
150
151impl HasEncoding for MichelsonContract {
155 fn encoding() -> Encoding {
156 Encoding::Custom
157 }
158}
159
160impl HasEncoding for MichelsonUnit {
161 fn encoding() -> Encoding {
162 Encoding::Custom
163 }
164}
165
166impl<Arg0, Arg1> HasEncoding for MichelsonPair<Arg0, Arg1>
167where
168 Arg0: Debug + PartialEq + Eq,
169 Arg1: Debug + PartialEq + Eq,
170{
171 fn encoding() -> Encoding {
172 Encoding::Custom
173 }
174}
175
176impl<Arg0, Arg1> HasEncoding for MichelsonOr<Arg0, Arg1>
177where
178 Arg0: Debug + PartialEq + Eq,
179 Arg1: Debug + PartialEq + Eq,
180{
181 fn encoding() -> Encoding {
182 Encoding::Custom
183 }
184}
185
186impl<Arg> HasEncoding for MichelsonOption<Arg>
187where
188 Arg: Debug + PartialEq + Eq,
189{
190 fn encoding() -> Encoding {
191 Encoding::Custom
192 }
193}
194
195impl HasEncoding for MichelsonString {
196 fn encoding() -> Encoding {
197 Encoding::Custom
198 }
199}
200
201impl HasEncoding for MichelsonBytes {
202 fn encoding() -> Encoding {
203 Encoding::Custom
204 }
205}
206
207impl HasEncoding for MichelsonInt {
208 fn encoding() -> Encoding {
209 Encoding::Custom
210 }
211}
212
213impl NomReader for MichelsonContract {
217 fn nom_read(input: &[u8]) -> NomResult<Self> {
218 map(
219 nom_read_micheline_bytes(Contract::nom_read),
220 MichelsonContract,
221 )(input)
222 }
223}
224
225impl NomReader for MichelsonUnit {
226 fn nom_read(input: &[u8]) -> NomResult<Self> {
227 map(
228 MichelinePrimNoArgsNoAnnots::<{ prim::UNIT_TAG }>::nom_read,
229 |_prim| MichelsonUnit,
230 )(input)
231 }
232}
233
234impl<Arg0, Arg1> NomReader for MichelsonPair<Arg0, Arg1>
235where
236 Arg0: NomReader + Debug + PartialEq + Eq,
237 Arg1: NomReader + Debug + PartialEq + Eq,
238{
239 fn nom_read(input: &[u8]) -> NomResult<Self> {
240 map(
241 MichelinePrim2ArgsNoAnnots::<_, _, { prim::PAIR_TAG }>::nom_read,
242 Into::into,
243 )(input)
244 }
245}
246
247impl<Arg0, Arg1> NomReader for MichelsonOr<Arg0, Arg1>
248where
249 Arg0: NomReader + Debug + PartialEq + Eq,
250 Arg1: NomReader + Debug + PartialEq + Eq,
251{
252 fn nom_read(input: &[u8]) -> NomResult<Self> {
253 alt((
254 map(
255 MichelinePrim1ArgNoAnnots::<_, { prim::LEFT_TAG }>::nom_read,
256 |MichelinePrim1ArgNoAnnots { arg }| Self::Left(arg),
257 ),
258 map(
259 MichelinePrim1ArgNoAnnots::<_, { prim::RIGHT_TAG }>::nom_read,
260 |MichelinePrim1ArgNoAnnots { arg }| Self::Right(arg),
261 ),
262 ))(input)
263 }
264}
265
266impl<Arg> NomReader for MichelsonOption<Arg>
267where
268 Arg: NomReader + Debug + PartialEq + Eq,
269{
270 fn nom_read(input: &[u8]) -> NomResult<Self> {
271 alt((
272 map(
273 MichelinePrimNoArgsNoAnnots::<{ prim::NONE_TAG }>::nom_read,
274 |_prim| Self(None),
275 ),
276 map(
277 MichelinePrim1ArgNoAnnots::<_, { prim::SOME_TAG }>::nom_read,
278 |MichelinePrim1ArgNoAnnots { arg }| Self(Some(arg)),
279 ),
280 ))(input)
281 }
282}
283
284impl NomReader for MichelsonString {
285 fn nom_read(input: &[u8]) -> NomResult<Self> {
286 map(nom_read_micheline_string, MichelsonString)(input)
287 }
288}
289
290impl NomReader for MichelsonBytes {
291 fn nom_read(input: &[u8]) -> NomResult<Self> {
292 map(nom_read_micheline_bytes(nom_read::bytes), MichelsonBytes)(input)
293 }
294}
295
296impl NomReader for MichelsonInt {
297 fn nom_read(input: &[u8]) -> NomResult<Self> {
298 map(nom_read_micheline_int, MichelsonInt)(input)
299 }
300}
301
302impl BinWriter for MichelsonContract {
306 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
307 bin_write_micheline_bytes(Contract::bin_write)(&self.0, output)
308 }
309}
310
311impl BinWriter for MichelsonUnit {
312 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
313 bin_write_prim_no_args_no_annots(prim::UNIT_TAG, output)
314 }
315}
316
317impl<Arg0, Arg1> BinWriter for MichelsonPair<Arg0, Arg1>
318where
319 Arg0: BinWriter + Debug + PartialEq + Eq,
320 Arg1: BinWriter + Debug + PartialEq + Eq,
321{
322 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
323 bin_write_prim_2_args_no_annots(prim::PAIR_TAG, &self.0, &self.1, output)
324 }
325}
326
327impl<Arg0, Arg1> From<MichelinePrim2ArgsNoAnnots<Arg0, Arg1, { prim::PAIR_TAG }>>
328 for MichelsonPair<Arg0, Arg1>
329where
330 Arg0: Debug + PartialEq + Eq,
331 Arg1: Debug + PartialEq + Eq,
332{
333 fn from(
334 micheline: MichelinePrim2ArgsNoAnnots<Arg0, Arg1, { prim::PAIR_TAG }>,
335 ) -> Self {
336 Self(micheline.arg1, micheline.arg2)
337 }
338}
339
340impl<Arg0, Arg1> From<MichelsonPair<Arg0, Arg1>>
341 for MichelinePrim2ArgsNoAnnots<Arg0, Arg1, { prim::PAIR_TAG }>
342where
343 Arg0: Debug + PartialEq + Eq,
344 Arg1: Debug + PartialEq + Eq,
345{
346 fn from(michelson: MichelsonPair<Arg0, Arg1>) -> Self {
347 Self {
348 arg1: michelson.0,
349 arg2: michelson.1,
350 }
351 }
352}
353
354impl<Arg0, Arg1> BinWriter for MichelsonOr<Arg0, Arg1>
355where
356 Arg0: BinWriter + Debug + PartialEq + Eq,
357 Arg1: BinWriter + Debug + PartialEq + Eq,
358{
359 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
360 match self {
361 MichelsonOr::Left(left) => {
362 bin_write_prim_1_arg_no_annots(prim::LEFT_TAG, left, output)
363 }
364 MichelsonOr::Right(right) => {
365 bin_write_prim_1_arg_no_annots(prim::RIGHT_TAG, right, output)
366 }
367 }
368 }
369}
370
371impl<Arg0, Arg1> From<MichelinePrim1ArgNoAnnots<Arg0, { prim::LEFT_TAG }>>
372 for MichelsonOr<Arg0, Arg1>
373where
374 Arg0: Debug + PartialEq + Eq,
375 Arg1: Debug + PartialEq + Eq,
376{
377 fn from(micheline: MichelinePrim1ArgNoAnnots<Arg0, { prim::LEFT_TAG }>) -> Self {
378 Self::Left(micheline.arg)
379 }
380}
381
382impl<Arg0, Arg1> From<MichelinePrim1ArgNoAnnots<Arg1, { prim::RIGHT_TAG }>>
383 for MichelsonOr<Arg0, Arg1>
384where
385 Arg0: Debug + PartialEq + Eq,
386 Arg1: Debug + PartialEq + Eq,
387{
388 fn from(micheline: MichelinePrim1ArgNoAnnots<Arg1, { prim::RIGHT_TAG }>) -> Self {
389 Self::Right(micheline.arg)
390 }
391}
392
393impl<Arg> BinWriter for MichelsonOption<Arg>
394where
395 Arg: BinWriter + Debug + PartialEq + Eq,
396{
397 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
398 match self {
399 MichelsonOption(None) => {
400 bin_write_prim_no_args_no_annots(prim::NONE_TAG, output)
401 }
402 MichelsonOption(Some(arg)) => {
403 bin_write_prim_1_arg_no_annots(prim::SOME_TAG, arg, output)
404 }
405 }
406 }
407}
408
409impl BinWriter for MichelsonString {
410 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
411 bin_write_micheline_string(&self.0, output)
412 }
413}
414
415impl BinWriter for MichelsonBytes {
416 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
417 bin_write_micheline_bytes(enc::bytes)(self.0.as_slice(), output)
418 }
419}
420
421impl BinWriter for MichelsonInt {
422 fn bin_write(&self, output: &mut Vec<u8>) -> BinResult {
423 bin_write_micheline_int(&self.0, output)
424 }
425}