clvm_utils/
curried_program.rs

1use clvm_traits::{
2    clvm_list, clvm_quote, destructure_list, destructure_quote, match_list, match_quote,
3    ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, MatchByte, ToClvm, ToClvmError,
4};
5
6#[derive(Debug, Clone)]
7pub struct CurriedProgram<P, A> {
8    pub program: P,
9    pub args: A,
10}
11
12impl<N, D: ClvmDecoder<Node = N>, P, A> FromClvm<D> for CurriedProgram<P, A>
13where
14    P: FromClvm<D>,
15    A: FromClvm<D>,
16{
17    fn from_clvm(decoder: &D, node: N) -> Result<Self, FromClvmError> {
18        let destructure_list!(_, destructure_quote!(program), args) =
19            <match_list!(MatchByte<2>, match_quote!(P), A)>::from_clvm(decoder, node)?;
20        Ok(Self { program, args })
21    }
22}
23
24impl<N, E: ClvmEncoder<Node = N>, P, A> ToClvm<E> for CurriedProgram<P, A>
25where
26    P: ToClvm<E>,
27    A: ToClvm<E>,
28{
29    fn to_clvm(&self, encoder: &mut E) -> Result<N, ToClvmError> {
30        clvm_list!(2, clvm_quote!(&self.program), &self.args).to_clvm(encoder)
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use std::fmt::Debug;
37
38    use clvm_traits::clvm_curried_args;
39    use clvmr::{serde::node_to_bytes, Allocator};
40
41    use super::*;
42
43    fn check<P, A>(program: &P, args: &A, expected: &str)
44    where
45        P: Debug + PartialEq + ToClvm<Allocator> + FromClvm<Allocator>,
46        A: Debug + PartialEq + ToClvm<Allocator> + FromClvm<Allocator>,
47    {
48        let a = &mut Allocator::new();
49
50        let curry = CurriedProgram {
51            program: &program,
52            args: &args,
53        }
54        .to_clvm(a)
55        .unwrap();
56        let actual = node_to_bytes(a, curry).unwrap();
57        assert_eq!(hex::encode(actual), expected);
58
59        let curried = CurriedProgram::<P, A>::from_clvm(a, curry).unwrap();
60        assert_eq!(&curried.program, program);
61        assert_eq!(&curried.args, args);
62    }
63
64    #[test]
65    fn curry() {
66        check(
67            &"xyz".to_string(),
68            &clvm_curried_args!("a".to_string(), "b".to_string(), "c".to_string()),
69            "ff02ffff018378797affff04ffff0161ffff04ffff0162ffff04ffff0163ff0180808080",
70        );
71    }
72}