use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::de::Error; use base64::{Engine as _, alphabet, engine::{GeneralPurpose, general_purpose}}; use lazy_static::lazy_static; lazy_static! { static ref ENGINE: GeneralPurpose = GeneralPurpose::new( &alphabet::STANDARD, general_purpose::NO_PAD ); } #[derive(Debug)] pub struct Base64Box(pub Vec); impl Serialize for Base64Box { fn serialize(&self, serializer: S) -> Result { serializer.collect_str(&ENGINE.encode(&self.0)) } } impl<'de> Deserialize<'de> for Base64Box { fn deserialize>(deserializer: D) -> Result { struct Vis; impl serde::de::Visitor<'_> for Vis { type Value = Base64Box; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a base64 string") } fn visit_str(self, v: &str) -> Result { ENGINE.decode(v).map(Base64Box).map_err(Error::custom) } } deserializer.deserialize_str(Vis) } }