#[macro_export]
macro_rules! base64_serde_type {
($visibility:vis $typename:ident, $engine:expr) => {
$visibility enum $typename {}
base64_serde_type!(impl_only, $typename, $engine);
};
(impl_only, $typename:ident, $engine:expr) => {
impl $typename {
pub fn serialize<S, Input>(
bytes: Input,
serializer: S,
) -> ::std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
Input: AsRef<[u8]>,
{
use base64::Engine as _;
serializer.serialize_str(&$engine.encode(bytes.as_ref()))
}
pub fn deserialize<'de, D, Output>(
deserializer: D,
) -> ::std::result::Result<Output, D::Error>
where
D: serde::Deserializer<'de>,
Output: From<Vec<u8>>,
{
struct Base64Visitor;
impl<'de> serde::de::Visitor<'de> for Base64Visitor {
type Value = Vec<u8>;
fn expecting(
&self,
formatter: &mut ::std::fmt::Formatter,
) -> ::std::fmt::Result {
write!(formatter, "base64 ASCII text")
}
fn visit_str<E>(self, v: &str) -> ::std::result::Result<Self::Value, E>
where
E: serde::de::Error,
{
use base64::Engine as _;
$engine.decode(v).map_err(serde::de::Error::custom)
}
}
deserializer
.deserialize_str(Base64Visitor)
.map(|vec| Output::from(vec))
}
}
};
}