klvm_traits/
klvm_encoder.rs1use klvmr::{Allocator, Atom, NodePtr};
2use num_bigint::BigInt;
3
4use crate::{klvm_list, klvm_quote, ToKlvm, ToKlvmError};
5
6pub trait KlvmEncoder: Sized {
7 type Node: Clone + ToKlvm<Self>;
8
9 fn encode_atom(&mut self, atom: Atom<'_>) -> Result<Self::Node, ToKlvmError>;
10 fn encode_pair(
11 &mut self,
12 first: Self::Node,
13 rest: Self::Node,
14 ) -> Result<Self::Node, ToKlvmError>;
15
16 fn encode_bigint(&mut self, number: BigInt) -> Result<Self::Node, ToKlvmError> {
17 let bytes = number.to_signed_bytes_be();
18 let mut slice = bytes.as_slice();
19
20 while !slice.is_empty() && slice[0] == 0 {
22 if slice.len() > 1 && (slice[1] & 0x80 == 0x80) {
23 break;
24 }
25 slice = &slice[1..];
26 }
27
28 self.encode_atom(Atom::Borrowed(slice))
29 }
30
31 fn encode_curried_arg(
32 &mut self,
33 first: Self::Node,
34 rest: Self::Node,
35 ) -> Result<Self::Node, ToKlvmError> {
36 const OP_C: u8 = 4;
37 klvm_list!(OP_C, klvm_quote!(first), rest).to_klvm(self)
38 }
39
40 fn clone_node(&self, node: &Self::Node) -> Self::Node {
44 node.clone()
45 }
46}
47
48impl KlvmEncoder for Allocator {
49 type Node = NodePtr;
50
51 fn encode_atom(&mut self, atom: Atom<'_>) -> Result<Self::Node, ToKlvmError> {
52 match atom {
53 Atom::Borrowed(bytes) => self.new_atom(bytes),
54 Atom::U32(bytes, _len) => self.new_small_number(u32::from_be_bytes(bytes)),
55 }
56 .or(Err(ToKlvmError::OutOfMemory))
57 }
58
59 fn encode_pair(
60 &mut self,
61 first: Self::Node,
62 rest: Self::Node,
63 ) -> Result<Self::Node, ToKlvmError> {
64 self.new_pair(first, rest).or(Err(ToKlvmError::OutOfMemory))
65 }
66
67 fn encode_bigint(&mut self, number: BigInt) -> Result<Self::Node, ToKlvmError> {
68 self.new_number(number).or(Err(ToKlvmError::OutOfMemory))
69 }
70}
71
72impl ToKlvm<Allocator> for NodePtr {
73 fn to_klvm(&self, _encoder: &mut Allocator) -> Result<NodePtr, ToKlvmError> {
74 Ok(*self)
75 }
76}