fedimint_core/encoding/
as_hex.rs

1//! Serde implementations using hex-encoded encodables
2//!
3//! Oftentimes it's convenient to de/serialize consensus encodable data
4//! as using consensus encoding (wrapped in hex encoding).
5//!
6//! If you have just a field use just:
7//!
8//! ```norust
9//! #[serde(with = "::fedimint_core::encoding::as_hex")] EncodableType,
10//! ```
11//!
12//! If you want to do it for the whole `struct`, use
13//! [`crate::serde_as_encodable_hex`] macro.
14
15use serde::Deserialize;
16
17use super::{Decodable, Encodable};
18use crate::module::registry::ModuleRegistry;
19
20pub fn serialize<T, S>(t: &T, ser: S) -> Result<S::Ok, S::Error>
21where
22    T: Encodable,
23    S: serde::Serializer,
24{
25    ser.serialize_str(&t.consensus_encode_to_hex())
26}
27
28pub fn deserialize<'de, T: Decodable, D>(de: D) -> Result<T, D::Error>
29where
30    D: serde::de::Deserializer<'de>,
31{
32    Decodable::consensus_decode_hex(&String::deserialize(de)?, &ModuleRegistry::default())
33        .map_err(|e| serde::de::Error::custom(format!("decodable deserialization failed: {e:#}")))
34}
35
36#[macro_export]
37macro_rules! serialize_as_encodable_hex {
38    ($name:ident) => {
39        impl Serialize for $name {
40            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
41            where
42                S: serde::Serializer,
43            {
44                use $crate::Encodable;
45                serializer.serialize_str(&self.consensus_encode_to_hex().map_err(|e| {
46                    serde::ser::Error::custom(format!("encodable serialization failed: {e:#}"))
47                })?)
48            }
49        }
50    };
51}
52
53#[macro_export]
54macro_rules! deserialize_as_encodable_hex {
55    ($name:ident) => {
56        impl<'de> Deserialize<'de> for $name {
57            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
58            where
59                D: serde::Deserializer<'de>,
60            {
61                $crate::Decodable::consensus_decode_hex(
62                    &String::deserialize(deserializer)?,
63                    &Default::default(),
64                )
65                .map_err(|e| {
66                    serde::de::Error::custom(format!("decodable deserialization failed: {e:#}"))
67                })
68            }
69        }
70    };
71}
72
73#[macro_export]
74macro_rules! serde_as_encodable_hex {
75    ($name:ident) => {
76        $crate::serialize_as_encodable_hex!($name);
77        $crate::deserialize_as_encodable_hex!($name);
78    };
79}