hpl_toolkit/compression/
default_impl.rs

1use crate::compression::ToNode;
2use anchor_lang::{prelude::*, solana_program::keccak};
3use std::collections::HashMap;
4
5macro_rules! impl_to_node_for_numbers {
6    ($($t:ty)+) => {
7        $(
8            impl ToNode for $t {
9                fn to_node(&self) -> [u8; 32] {
10                    let bytes = self.clone().to_le_bytes();
11                    keccak::hashv(&[bytes.as_ref()][..]).to_bytes()
12                }
13            }
14        )+
15    };
16}
17impl_to_node_for_numbers!(u8 u16 u32 u64 i8 i16 i32 i64 f32 f64);
18
19impl ToNode for String {
20    fn to_node(&self) -> [u8; 32] {
21        keccak::hashv(&[self.clone().as_bytes()][..]).to_bytes()
22    }
23}
24
25impl<T: ToNode> ToNode for Vec<T> {
26    fn to_node(&self) -> [u8; 32] {
27        let mut seeds: Vec<[u8; 32]> = vec![];
28        for item in self {
29            let node = item.to_node();
30            seeds.push(node);
31        }
32        let seeds_refs: Vec<&[u8]> = seeds.iter().map(|node| &node[..]).collect();
33        keccak::hashv(&seeds_refs[..]).to_bytes()
34    }
35}
36
37impl ToNode for Pubkey {
38    fn to_node(&self) -> [u8; 32] {
39        self.to_bytes()
40    }
41}
42
43impl ToNode for bool {
44    fn to_node(&self) -> [u8; 32] {
45        let bytes = self.clone().try_to_vec().unwrap();
46        keccak::hashv(&[bytes.as_ref()][..]).to_bytes()
47    }
48}
49
50impl<T: ToNode> ToNode for Option<T> {
51    fn to_node(&self) -> [u8; 32] {
52        match self {
53            Some(value) => value.to_node(),
54            None => keccak::hashv(&[&[0u8][..]][..]).to_bytes(),
55        }
56    }
57}
58
59impl<V: ToNode> ToNode for HashMap<String, V> {
60    fn to_node(&self) -> [u8; 32] {
61        let mut seeds: Vec<[u8; 32]> = vec![];
62        for (key, value) in self {
63            seeds.push(key.to_node());
64            seeds.push(value.to_node());
65        }
66        let seeds_refs: Vec<&[u8]> = seeds.iter().map(|node| &node[..]).collect();
67        keccak::hashv(&seeds_refs[..]).to_bytes()
68    }
69}
70
71impl ToNode for [u8; 32] {
72    fn to_node(&self) -> [u8; 32] {
73        *self
74    }
75}
76
77impl<A: ToNode, B: ToNode> ToNode for (A, B) {
78    fn to_node(&self) -> [u8; 32] {
79        let mut seeds: Vec<[u8; 32]> = vec![];
80        seeds.push(self.0.to_node());
81        seeds.push(self.1.to_node());
82        let seeds_refs: Vec<&[u8]> = seeds.iter().map(|node| &node[..]).collect();
83        keccak::hashv(&seeds_refs[..]).to_bytes()
84    }
85}
86impl<A: ToNode, B: ToNode, C: ToNode> ToNode for (A, B, C) {
87    fn to_node(&self) -> [u8; 32] {
88        let mut seeds: Vec<[u8; 32]> = vec![];
89        seeds.push(self.0.to_node());
90        seeds.push(self.1.to_node());
91        let seeds_refs: Vec<&[u8]> = seeds.iter().map(|node| &node[..]).collect();
92        keccak::hashv(&seeds_refs[..]).to_bytes()
93    }
94}