Skip to main content

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()).map_err(
33        |e| {
34            serde::de::Error::custom(format!(
35                "decodable deserialization failed: {}",
36                crate::util::FmtCompact::fmt_compact(&e)
37            ))
38        },
39    )
40}
41
42#[macro_export]
43macro_rules! serialize_as_encodable_hex {
44    ($name:ident) => {
45        impl Serialize for $name {
46            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
47            where
48                S: serde::Serializer,
49            {
50                use $crate::Encodable;
51                serializer.serialize_str(&self.consensus_encode_to_hex().map_err(|e| {
52                    serde::ser::Error::custom(format!("encodable serialization failed: {e:#}"))
53                })?)
54            }
55        }
56    };
57}
58
59#[macro_export]
60macro_rules! deserialize_as_encodable_hex {
61    ($name:ident) => {
62        impl<'de> Deserialize<'de> for $name {
63            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64            where
65                D: serde::Deserializer<'de>,
66            {
67                $crate::Decodable::consensus_decode_hex(
68                    &String::deserialize(deserializer)?,
69                    &Default::default(),
70                )
71                .map_err(|e| {
72                    serde::de::Error::custom(format!(
73                        "decodable deserialization failed: {}",
74                        $crate::util::FmtCompact::fmt_compact(&e)
75                    ))
76                })
77            }
78        }
79    };
80}
81
82#[macro_export]
83macro_rules! serde_as_encodable_hex {
84    ($name:ident) => {
85        $crate::serialize_as_encodable_hex!($name);
86        $crate::deserialize_as_encodable_hex!($name);
87    };
88}
89
90#[cfg(test)]
91mod tests;