2022-06-21 01:49:42 +00:00
|
|
|
use serde::{de::Error, Deserialize};
|
|
|
|
use std::{
|
|
|
|
fmt::Display,
|
|
|
|
ops::{Deref, DerefMut},
|
|
|
|
str::FromStr,
|
|
|
|
};
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub(crate) struct Optional<T> {
|
|
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
|
|
inner: Option<T>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Deref for Optional<T> {
|
|
|
|
type Target = Option<T>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> DerefMut for Optional<T> {
|
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
|
|
&mut self.inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> From<Option<T>> for Optional<T> {
|
|
|
|
fn from(inner: Option<T>) -> Self {
|
|
|
|
Optional { inner }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> From<Optional<T>> for Option<T> {
|
|
|
|
fn from(e: Optional<T>) -> Self {
|
|
|
|
e.inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> Optional<T> {
|
|
|
|
pub fn as_ref(&self) -> Option<&T> {
|
|
|
|
self.inner.as_ref()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_deref(&self) -> Option<&T::Target>
|
|
|
|
where
|
|
|
|
T: Deref,
|
|
|
|
{
|
|
|
|
self.inner.as_deref()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'de, T> Deserialize<'de> for Optional<T>
|
|
|
|
where
|
|
|
|
T: FromStr,
|
|
|
|
T::Err: Display,
|
|
|
|
{
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
where
|
|
|
|
D: serde::Deserializer<'de>,
|
|
|
|
{
|
|
|
|
let s: Option<String> = Deserialize::<'de>::deserialize(deserializer)?;
|
2022-06-21 18:28:05 +00:00
|
|
|
match s.as_deref().map(|s| s.trim()) {
|
2022-06-21 01:49:42 +00:00
|
|
|
None | Some("") => Ok(Optional { inner: None }),
|
|
|
|
Some(s) => T::from_str(&s)
|
|
|
|
.map_err(D::Error::custom)
|
|
|
|
.map(Some)
|
|
|
|
.map(|inner| Optional { inner }),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|