use serde::{
Deserialize, Deserializer, Serialize, Serializer,
de::{self, Visitor},
};
use crate::{GString, GStringError, Validator};
use core::{fmt, marker::PhantomData};
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::string::String;
impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Serialize
for GString<V, MIN, MAX, ASCII_ONLY>
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
struct GStringVisitor<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>(
PhantomData<V>,
);
impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Visitor<'de>
for GStringVisitor<V, MIN, MAX, ASCII_ONLY>
where
V: Validator,
GStringError<V::Err>: fmt::Display,
{
type Value = GString<V, MIN, MAX, ASCII_ONLY>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"a string with length between {} and {}{}",
MIN,
MAX,
if ASCII_ONLY { " (ASCII only)" } else { "" }
)
}
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
GString::try_new(v).map_err(de::Error::custom)
}
#[cfg(feature = "alloc")]
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: de::Error,
{
GString::try_from(v).map_err(de::Error::custom)
}
}
impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Deserialize<'de>
for GString<V, MIN, MAX, ASCII_ONLY>
where
V: Validator,
GStringError<V::Err>: fmt::Display,
{
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_str(GStringVisitor(PhantomData))
}
}
#[cfg(feature = "secret")]
mod secret_serde {
use crate::{GSecret, GStringError, Validator};
use core::{fmt, marker::PhantomData};
use serde::{
Deserialize, Deserializer,
de::{self, Visitor},
};
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::string::String;
struct GSecretVisitor<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>(
PhantomData<V>,
);
impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Visitor<'de>
for GSecretVisitor<V, MIN, MAX, ASCII_ONLY>
where
V: Validator,
GStringError<V::Err>: fmt::Display,
{
type Value = GSecret<V, MIN, MAX, ASCII_ONLY>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"a secret string between {} and {}{}",
MIN,
MAX,
if ASCII_ONLY { " (ASCII only)" } else { "" }
)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
GSecret::try_new(v).map_err(de::Error::custom)
}
#[cfg(feature = "alloc")]
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: de::Error,
{
GSecret::try_from(v).map_err(de::Error::custom)
}
}
impl<'de, V, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool> Deserialize<'de>
for GSecret<V, MIN, MAX, ASCII_ONLY>
where
V: Validator,
GStringError<V::Err>: fmt::Display,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(GSecretVisitor(PhantomData))
}
}
}