1use molecule::prelude::Entity;
4use musig2::{
5 BinaryEncoding, CompactSignature, PartialSignature, PubNonce, SCHNORR_SIGNATURE_SIZE,
6};
7use serde::{de::Error, Deserialize, Deserializer, Serializer};
8use serde_with::{serde_conv, DeserializeAs, SerializeAs};
9
10pub fn from_hex<'de, D, E>(deserializer: D) -> Result<E, D::Error>
11where
12 D: Deserializer<'de>,
13 E: TryFrom<Vec<u8>>,
14 E::Error: core::fmt::Debug,
15{
16 String::deserialize(deserializer)
17 .and_then(|string| {
18 let hex_str = string
21 .strip_prefix("0x")
22 .or_else(|| string.strip_prefix("0X"))
23 .unwrap_or(&string);
24 hex::decode(hex_str).map_err(|err| {
25 Error::custom(format!(
26 "failed to decode hex string {}: {:?}",
27 &string, err
28 ))
29 })
30 })
31 .and_then(|vec| {
32 vec.try_into().map_err(|err| {
33 Error::custom(format!("failed to convert vector into type: {:?}", err))
34 })
35 })
36}
37
38pub fn to_hex<E, S>(e: E, serializer: S) -> Result<S::Ok, S::Error>
39where
40 E: AsRef<[u8]>,
41 S: Serializer,
42{
43 to_hex_with_prefix(e, serializer, true)
44}
45
46fn to_hex_with_prefix<E, S>(e: E, serializer: S, with_prefix: bool) -> Result<S::Ok, S::Error>
47where
48 E: AsRef<[u8]>,
49 S: Serializer,
50{
51 let hex_str = hex::encode(e.as_ref());
52 let prefix = if with_prefix { "0x" } else { "" };
53 serializer.serialize_str(&format!("{}{}", prefix, hex_str))
54}
55
56pub struct SliceHex;
57
58impl<T> SerializeAs<T> for SliceHex
59where
60 T: AsRef<[u8]>,
61{
62 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
63 where
64 S: Serializer,
65 {
66 to_hex_with_prefix(source, serializer, true)
67 }
68}
69
70impl<'de, T> DeserializeAs<'de, T> for SliceHex
71where
72 T: TryFrom<Vec<u8>>,
73 T::Error: core::fmt::Debug,
74{
75 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
76 where
77 D: Deserializer<'de>,
78 {
79 from_hex(deserializer)
80 }
81}
82
83pub struct SliceHexNoPrefix;
84
85impl<T> SerializeAs<T> for SliceHexNoPrefix
86where
87 T: AsRef<[u8]>,
88{
89 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
90 where
91 S: Serializer,
92 {
93 to_hex_with_prefix(source, serializer, false)
94 }
95}
96
97impl<'de, T> DeserializeAs<'de, T> for SliceHexNoPrefix
98where
99 T: TryFrom<Vec<u8>>,
100 T::Error: core::fmt::Debug,
101{
102 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
103 where
104 D: Deserializer<'de>,
105 {
106 from_hex(deserializer)
107 }
108}
109
110pub struct EntityHex;
111
112impl<T> SerializeAs<T> for EntityHex
113where
114 T: Entity,
115{
116 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
117 where
118 S: Serializer,
119 {
120 to_hex(source.as_slice(), serializer)
121 }
122}
123
124impl<'de, T> DeserializeAs<'de, T> for EntityHex
125where
126 T: Entity,
127{
128 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
129 where
130 D: Deserializer<'de>,
131 {
132 let v: Vec<u8> = from_hex(deserializer)?;
133 T::from_slice(&v).map_err(Error::custom)
134 }
135}
136
137macro_rules! uint_as_hex {
138 ($name:ident, $ty:ty) => {
139 serde_conv!(
140 pub $name,
141 $ty,
142 |u: &$ty| format!("0x{:x}", u),
143 |hex: String| -> Result<$ty, String> {
144 let bytes = hex.as_bytes();
145 if bytes.len() < 3 || &bytes[..2] != b"0x" {
146 return Err(format!("uint hex string does not start with 0x: {}", hex));
147 }
148 if bytes.len() > 3 && &bytes[2..3] == b"0" {
149 return Err(format!("uint hex string starts with redundant leading zeros: {}", hex));
150 };
151 <$ty>::from_str_radix(&hex[2..], 16)
152 .map_err(|err| format!("failed to parse uint hex {}: {:?}", hex, err))
153 }
154 );
155 };
156}
157
158uint_as_hex!(U128Hex, u128);
159uint_as_hex!(U64Hex, u64);
160uint_as_hex!(U32Hex, u32);
161uint_as_hex!(U16Hex, u16);
162
163pub mod duration_hex {
165 use core::time::Duration;
166 use serde::{Deserialize, Deserializer, Serializer};
167
168 pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
169 where
170 S: Serializer,
171 {
172 let nanos = duration.as_secs();
173 serializer.serialize_str(&format!("0x{:x}", nanos))
174 }
175
176 pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
177 where
178 D: Deserializer<'de>,
179 {
180 let hex_str = String::deserialize(deserializer)?;
181 let seconds = u64::from_str_radix(&hex_str[2..], 16).map_err(|err| {
182 serde::de::Error::custom(format!(
183 "failed to parse duration hex {}: {:?}",
184 hex_str, err
185 ))
186 })?;
187
188 Ok(Duration::from_secs(seconds))
189 }
190}
191
192pub struct SliceBase58;
193
194impl<T> SerializeAs<T> for SliceBase58
195where
196 T: AsRef<[u8]>,
197{
198 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
199 where
200 S: Serializer,
201 {
202 serializer.serialize_str(&bs58::encode(source).into_string())
203 }
204}
205
206impl<'de, T> DeserializeAs<'de, T> for SliceBase58
207where
208 T: TryFrom<Vec<u8>>,
209 T::Error: core::fmt::Debug,
210{
211 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
212 where
213 D: Deserializer<'de>,
214 {
215 String::deserialize(deserializer)
216 .and_then(|s| {
217 bs58::decode(&s).into_vec().map_err(|err| {
218 Error::custom(format!("failed to decode base58 string {}: {:?}", &s, err))
219 })
220 })
221 .and_then(|vec| {
222 vec.try_into().map_err(|err| {
223 Error::custom(format!("failed to convert vector into type: {:?}", err))
224 })
225 })
226 }
227}
228
229pub struct CompactSignatureAsBytes;
231
232impl SerializeAs<CompactSignature> for CompactSignatureAsBytes {
233 fn serialize_as<S>(signature: &CompactSignature, serializer: S) -> Result<S::Ok, S::Error>
234 where
235 S: Serializer,
236 {
237 serializer.serialize_bytes(&signature.to_bytes())
238 }
239}
240
241impl<'de> DeserializeAs<'de, CompactSignature> for CompactSignatureAsBytes {
242 fn deserialize_as<D>(deserializer: D) -> Result<CompactSignature, D::Error>
243 where
244 D: Deserializer<'de>,
245 {
246 let bytes: Vec<u8> = Deserialize::deserialize(deserializer)?;
247 if bytes.len() != SCHNORR_SIGNATURE_SIZE {
248 return Err(Error::custom("expected 64 bytes"));
249 }
250 CompactSignature::from_bytes(&bytes).map_err(Error::custom)
251 }
252}
253
254pub struct PubNonceAsBytes;
256
257impl SerializeAs<PubNonce> for PubNonceAsBytes {
258 fn serialize_as<S>(nonce: &PubNonce, serializer: S) -> Result<S::Ok, S::Error>
259 where
260 S: Serializer,
261 {
262 serializer.serialize_bytes(&nonce.to_bytes())
263 }
264}
265
266impl<'de> DeserializeAs<'de, PubNonce> for PubNonceAsBytes {
267 fn deserialize_as<D>(deserializer: D) -> Result<PubNonce, D::Error>
268 where
269 D: Deserializer<'de>,
270 {
271 let bytes: Vec<u8> = Deserialize::deserialize(deserializer)?;
272 if bytes.len() != 66 {
273 return Err(Error::custom("expected 66 bytes"));
274 }
275 PubNonce::from_bytes(&bytes).map_err(Error::custom)
276 }
277}
278
279pub struct PartialSignatureAsBytes;
281
282impl SerializeAs<PartialSignature> for PartialSignatureAsBytes {
283 fn serialize_as<S>(signature: &PartialSignature, serializer: S) -> Result<S::Ok, S::Error>
284 where
285 S: Serializer,
286 {
287 let bytes: [u8; 32] = signature.serialize();
288 serde::Serialize::serialize(&bytes, serializer)
289 }
290}
291
292impl<'de> DeserializeAs<'de, PartialSignature> for PartialSignatureAsBytes {
293 fn deserialize_as<D>(deserializer: D) -> Result<PartialSignature, D::Error>
294 where
295 D: Deserializer<'de>,
296 {
297 let bytes = <[u8; 32]>::deserialize(deserializer)?;
298 PartialSignature::from_slice(&bytes).map_err(Error::custom)
299 }
300}