Implement Serialize/Deserialize for MaybeUndefine<T>.
This commit is contained in:
parent
37e21c54fa
commit
0259a35782
@ -1,5 +1,5 @@
|
|||||||
use crate::{registry, InputValueResult, InputValueType, Type, Value};
|
use crate::{registry, InputValueResult, InputValueType, Type, Value};
|
||||||
use serde::Serialize;
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// Similar to `Option`, but it has three states, `undefined`, `null` and `x`.
|
/// Similar to `Option`, but it has three states, `undefined`, `null` and `x`.
|
||||||
@ -46,14 +46,19 @@ use std::borrow::Cow;
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Serialize, Clone, Debug)]
|
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum MaybeUndefined<T> {
|
pub enum MaybeUndefined<T> {
|
||||||
Undefined,
|
Undefined,
|
||||||
Null,
|
Null,
|
||||||
Value(T),
|
Value(T),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Default for MaybeUndefined<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> MaybeUndefined<T> {
|
impl<T> MaybeUndefined<T> {
|
||||||
/// Returns true if the MaybeUndefined<T> is undefined.
|
/// Returns true if the MaybeUndefined<T> is undefined.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -136,15 +141,107 @@ impl<T: InputValueType> InputValueType for MaybeUndefined<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Serialize> Serialize for MaybeUndefined<T> {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
|
||||||
|
match self {
|
||||||
|
MaybeUndefined::Value(value) => value.serialize(serializer),
|
||||||
|
_ => serializer.serialize_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, T> Deserialize<'de> for MaybeUndefined<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<MaybeUndefined<T>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Option::<T>::deserialize(deserializer).map(|value| match value {
|
||||||
|
Some(value) => MaybeUndefined::Value(value),
|
||||||
|
None => MaybeUndefined::Null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_optional_type() {
|
fn test_maybe_undefined_type() {
|
||||||
assert_eq!(MaybeUndefined::<i32>::type_name(), "Int");
|
assert_eq!(MaybeUndefined::<i32>::type_name(), "Int");
|
||||||
assert_eq!(MaybeUndefined::<i32>::qualified_type_name(), "Int");
|
assert_eq!(MaybeUndefined::<i32>::qualified_type_name(), "Int");
|
||||||
assert_eq!(&MaybeUndefined::<i32>::type_name(), "Int");
|
assert_eq!(&MaybeUndefined::<i32>::type_name(), "Int");
|
||||||
assert_eq!(&MaybeUndefined::<i32>::qualified_type_name(), "Int");
|
assert_eq!(&MaybeUndefined::<i32>::qualified_type_name(), "Int");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_maybe_undefined_serde() {
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_string(&MaybeUndefined::Value(100i32)).unwrap(),
|
||||||
|
"100"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<MaybeUndefined<i32>>("100").unwrap(),
|
||||||
|
MaybeUndefined::Value(100)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<MaybeUndefined<i32>>("null").unwrap(),
|
||||||
|
MaybeUndefined::Null
|
||||||
|
);
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
|
||||||
|
struct A {
|
||||||
|
a: MaybeUndefined<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_string(&A {
|
||||||
|
a: MaybeUndefined::Value(100i32)
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
r#"{"a":100}"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_string(&A {
|
||||||
|
a: MaybeUndefined::Null,
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
r#"{"a":null}"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_string(&A {
|
||||||
|
a: MaybeUndefined::Undefined,
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
r#"{"a":null}"#
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<A>(r#"{"a":100}"#).unwrap(),
|
||||||
|
A {
|
||||||
|
a: MaybeUndefined::Value(100i32)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<A>(r#"{"a":null}"#).unwrap(),
|
||||||
|
A {
|
||||||
|
a: MaybeUndefined::Null
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::from_str::<A>(r#"{}"#).unwrap(),
|
||||||
|
A {
|
||||||
|
a: MaybeUndefined::Null
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user