clvm_traits/
clvm_decoder.rs1use clvmr::{allocator::SExp, Allocator, Atom, NodePtr};
2use num_bigint::BigInt;
3
4use crate::{
5 destructure_list, destructure_quote, match_list, match_quote, FromClvm, FromClvmError,
6 MatchByte,
7};
8
9pub trait ClvmDecoder: Sized {
10 type Node: Clone + FromClvm<Self>;
11
12 fn decode_atom(&self, node: &Self::Node) -> Result<Atom<'_>, FromClvmError>;
13 fn decode_pair(&self, node: &Self::Node) -> Result<(Self::Node, Self::Node), FromClvmError>;
14
15 fn decode_bigint(&self, node: &Self::Node) -> Result<BigInt, FromClvmError> {
16 let atom = self.decode_atom(node)?;
17 Ok(BigInt::from_signed_bytes_be(atom.as_ref()))
18 }
19
20 fn decode_curried_arg(
21 &self,
22 node: &Self::Node,
23 ) -> Result<(Self::Node, Self::Node), FromClvmError> {
24 let destructure_list!(_, destructure_quote!(first), rest) =
25 <match_list!(MatchByte<4>, match_quote!(Self::Node), Self::Node)>::from_clvm(
26 self,
27 node.clone(),
28 )?;
29 Ok((first, rest))
30 }
31
32 fn clone_node(&self, node: &Self::Node) -> Self::Node {
36 node.clone()
37 }
38}
39
40impl ClvmDecoder for Allocator {
41 type Node = NodePtr;
42
43 fn decode_atom(&self, node: &Self::Node) -> Result<Atom<'_>, FromClvmError> {
44 if let SExp::Atom = self.sexp(*node) {
45 Ok(self.atom(*node))
46 } else {
47 Err(FromClvmError::ExpectedAtom)
48 }
49 }
50
51 fn decode_pair(&self, node: &Self::Node) -> Result<(Self::Node, Self::Node), FromClvmError> {
52 if let SExp::Pair(first, rest) = self.sexp(*node) {
53 Ok((first, rest))
54 } else {
55 Err(FromClvmError::ExpectedPair)
56 }
57 }
58
59 fn decode_bigint(&self, node: &Self::Node) -> Result<BigInt, FromClvmError> {
60 if let SExp::Atom = self.sexp(*node) {
61 Ok(self.number(*node))
62 } else {
63 Err(FromClvmError::ExpectedAtom)
64 }
65 }
66}
67
68impl FromClvm<Allocator> for NodePtr {
69 fn from_clvm(_decoder: &Allocator, node: NodePtr) -> Result<Self, FromClvmError> {
70 Ok(node)
71 }
72}