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