snarkvm_console_network/helpers/
object.rs1use crate::prelude::*;
17
18use anyhow::Result;
19use bech32::{self, FromBase32, ToBase32};
20use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
21use std::borrow::Borrow;
22
23pub trait Bech32Object<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send>:
24 From<T>
25 + Deref<Target = T>
26 + Clone
27 + Debug
28 + Display
29 + ToBytes
30 + FromBytes
31 + PartialEq
32 + Eq
33 + Serialize
34 + DeserializeOwned
35 + Sync
36 + Send
37{
38 fn prefix() -> String;
39}
40
41#[macro_export]
43macro_rules! hrp4 {
44 ( $persona: expr ) => {{
45 $crate::const_assert!($persona.len() == 4);
46 let p = $persona.as_bytes();
47 u32::from_le_bytes([p[0], p[1], p[2], p[3]])
48 }};
49}
50
51#[derive(Clone, PartialEq, Eq, Hash)]
52pub struct AleoObject<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32>(T);
53
54impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Bech32Object<T>
55 for AleoObject<T, PREFIX>
56{
57 #[inline]
58 fn prefix() -> String {
59 String::from_utf8(PREFIX.to_le_bytes().to_vec()).expect("Failed to convert prefix to string")
60 }
61}
62
63impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> From<T>
64 for AleoObject<T, PREFIX>
65{
66 #[inline]
67 fn from(data: T) -> Self {
68 Self(data)
69 }
70}
71
72impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> FromBytes
73 for AleoObject<T, PREFIX>
74{
75 #[inline]
77 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
78 Ok(Self(FromBytes::read_le(&mut reader)?))
79 }
80}
81
82impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> ToBytes
83 for AleoObject<T, PREFIX>
84{
85 #[inline]
87 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
88 self.0.write_le(&mut writer)
89 }
90}
91
92impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> FromStr
93 for AleoObject<T, PREFIX>
94{
95 type Err = Error;
96
97 #[inline]
99 fn from_str(string: &str) -> Result<Self, Self::Err> {
100 let (hrp, data, variant) = bech32::decode(string)?;
101 if hrp.as_bytes() != PREFIX.to_le_bytes() {
102 bail!("Invalid prefix for a bech32m hash: {hrp}")
103 };
104 if data.is_empty() {
105 bail!("Bech32m hash data is empty")
106 }
107 if variant != bech32::Variant::Bech32m {
108 bail!("Hash is not a bech32m hash")
109 }
110 Ok(Self::read_le(&*Vec::from_base32(&data)?)?)
111 }
112}
113
114impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Display
115 for AleoObject<T, PREFIX>
116{
117 #[inline]
118 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
119 bech32::encode_to_fmt(
120 f,
121 &Self::prefix(),
122 self.0.to_bytes_le().expect("Failed to write data as bytes").to_base32(),
123 bech32::Variant::Bech32m,
124 )
125 .expect("Failed to encode in bech32m")
126 }
127}
128
129impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Debug
130 for AleoObject<T, PREFIX>
131{
132 #[inline]
133 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
134 write!(f, "AleoObject {{ hrp: {:?}, data: {:?} }}", &Self::prefix(), self.0)
135 }
136}
137
138impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Serialize
139 for AleoObject<T, PREFIX>
140{
141 #[inline]
142 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
143 match serializer.is_human_readable() {
144 true => serializer.collect_str(self),
145 false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
146 }
147 }
148}
149
150impl<'de, T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Deserialize<'de>
151 for AleoObject<T, PREFIX>
152{
153 #[inline]
154 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
155 match deserializer.is_human_readable() {
156 true => FromStr::from_str(&String::deserialize(deserializer)?).map_err(de::Error::custom),
157 false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, &Self::prefix()),
158 }
159 }
160}
161
162impl<T: Default + Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Default
163 for AleoObject<T, PREFIX>
164{
165 fn default() -> Self {
166 Self(T::default())
167 }
168}
169
170impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Deref
171 for AleoObject<T, PREFIX>
172{
173 type Target = T;
174
175 #[inline]
176 fn deref(&self) -> &Self::Target {
177 &self.0
178 }
179}
180
181impl<T: Clone + Debug + ToBytes + FromBytes + PartialEq + Eq + Sync + Send, const PREFIX: u32> Borrow<T>
182 for AleoObject<T, PREFIX>
183{
184 #[inline]
185 fn borrow(&self) -> &T {
186 &self.0
187 }
188}