use base64::{decode, encode};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone)]
pub struct Base64String(pub String);
impl Base64String {
pub fn new(thing: String) -> Base64String {
Base64String(thing)
}
}
#[cfg(test)]
mod base64string_tests {
use super::*;
#[test]
fn it_creates_a_new_base64string() {
assert_eq!(
Base64String::new(String::from("abc123")),
Base64String(String::from("abc123"))
);
}
}
impl fmt::Display for Base64String {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0.to_string())
}
}
#[cfg(test)]
mod display_amount_tests {
use super::*;
#[test]
fn it_displays_as_a_string() {
assert_eq!(
format!("{}", Base64String(String::from("abc123"))),
"abc123"
);
}
}
impl Serialize for Base64String {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let formatted_string = format!("{}", self);
let encoded_string = encode(&formatted_string);
serializer.serialize_str(&encoded_string)
}
}
#[cfg(test)]
mod serialize_amount_tests {
use super::*;
use serde_json;
#[test]
fn it_displays_data_as_base64_encoded() {
let base64string = Base64String(String::from("Pizza"));
assert_eq!(
serde_json::to_string(&base64string).unwrap(),
"\"UGl6emE=\""
);
}
}
impl<'de> Deserialize<'de> for Base64String {
fn deserialize<D>(d: D) -> Result<Base64String, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(d)?;
let decoded_vec = decode(&s).unwrap();
let decoded_string = String::from_utf8(decoded_vec).unwrap();
Ok(Base64String::new(decoded_string))
}
}
#[cfg(test)]
mod deserialize_base64string_tests {
use super::*;
use serde_json;
#[test]
fn it_decodes_base64() {
let data: Base64String = serde_json::from_str("\"UGl6emE=\"").unwrap();
assert_eq!(data, Base64String(String::from("Pizza")));
}
}