use crate::{formats, DeserializeAs, SerializeAs};
use serde::de::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::convert::{TryFrom, TryInto};
use std::default::Default;
use std::marker::PhantomData;
#[derive(Copy, Clone, Debug, Default)]
pub struct Base64<CHARSET: CharacterSet = Standard, PADDING: formats::Format = formats::Padded>(
PhantomData<(CHARSET, PADDING)>,
);
impl<T, CHARSET> SerializeAs<T> for Base64<CHARSET, formats::Padded>
where
T: AsRef<[u8]>,
CHARSET: CharacterSet,
{
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
base64_crate::encode_config(source, base64_crate::Config::new(CHARSET::charset(), true))
.serialize(serializer)
}
}
impl<T, CHARSET> SerializeAs<T> for Base64<CHARSET, formats::Unpadded>
where
T: AsRef<[u8]>,
CHARSET: CharacterSet,
{
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
base64_crate::encode_config(source, base64_crate::Config::new(CHARSET::charset(), false))
.serialize(serializer)
}
}
impl<'de, T, CHARSET, FORMAT> DeserializeAs<'de, T> for Base64<CHARSET, FORMAT>
where
T: TryFrom<Vec<u8>>,
CHARSET: CharacterSet,
FORMAT: formats::Format,
{
fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
{
String::deserialize(deserializer)
.and_then(|s| {
base64_crate::decode_config(
&*s,
base64_crate::Config::new(CHARSET::charset(), false),
)
.map_err(Error::custom)
})
.and_then(|vec: Vec<u8>| {
let length = vec.len();
vec.try_into().map_err(|_e: T::Error| {
Error::custom(format!(
"Can't convert a Byte Vector of length {} to the output type.",
length
))
})
})
}
}
pub trait CharacterSet {
fn charset() -> base64_crate::CharacterSet;
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Standard;
impl CharacterSet for Standard {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::Standard
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct UrlSafe;
impl CharacterSet for UrlSafe {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::UrlSafe
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Crypt;
impl CharacterSet for Crypt {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::Crypt
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Bcrypt;
impl CharacterSet for Bcrypt {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::Bcrypt
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct ImapMutf7;
impl CharacterSet for ImapMutf7 {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::ImapMutf7
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct BinHex;
impl CharacterSet for BinHex {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::BinHex
}
}