clvk_traits/
clvk_encoder.rs1use clvkr::{Allocator, Atom, NodePtr};
2use num_bigint::BigInt;
3
4use crate::{ToClvk, ToClvkError, clvk_list, clvk_quote};
5
6pub trait ClvkEncoder: Sized {
7 type Node: Clone + ToClvk<Self>;
8
9 fn encode_atom(&mut self, atom: Atom<'_>) -> Result<Self::Node, ToClvkError>;
10 fn encode_pair(
11 &mut self,
12 first: Self::Node,
13 rest: Self::Node,
14 ) -> Result<Self::Node, ToClvkError>;
15
16 fn encode_bigint(&mut self, number: BigInt) -> Result<Self::Node, ToClvkError> {
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, ToClvkError> {
36 const OP_C: u8 = 4;
37 clvk_list!(OP_C, clvk_quote!(first), rest).to_clvk(self)
38 }
39
40 fn clone_node(&self, node: &Self::Node) -> Self::Node {
44 node.clone()
45 }
46}
47
48impl ClvkEncoder for Allocator {
49 type Node = NodePtr;
50
51 fn encode_atom(&mut self, atom: Atom<'_>) -> Result<Self::Node, ToClvkError> {
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(ToClvkError::OutOfMemory))
57 }
58
59 fn encode_pair(
60 &mut self,
61 first: Self::Node,
62 rest: Self::Node,
63 ) -> Result<Self::Node, ToClvkError> {
64 self.new_pair(first, rest).or(Err(ToClvkError::OutOfMemory))
65 }
66
67 fn encode_bigint(&mut self, number: BigInt) -> Result<Self::Node, ToClvkError> {
68 self.new_number(number).or(Err(ToClvkError::OutOfMemory))
69 }
70}
71
72impl ToClvk<Allocator> for NodePtr {
73 fn to_clvk(&self, _encoder: &mut Allocator) -> Result<NodePtr, ToClvkError> {
74 Ok(*self)
75 }
76}