diff --git a/libs/deer/src/impls/core.rs b/libs/deer/src/impls/core.rs index 4e08ee1bf35..538ffa6c6d1 100644 --- a/libs/deer/src/impls/core.rs +++ b/libs/deer/src/impls/core.rs @@ -3,6 +3,7 @@ mod atomic; mod bool; mod floating; mod integral; +mod marker; mod non_zero; mod string; mod unit; diff --git a/libs/deer/src/impls/core/marker.rs b/libs/deer/src/impls/core/marker.rs new file mode 100644 index 00000000000..24abd0a6129 --- /dev/null +++ b/libs/deer/src/impls/core/marker.rs @@ -0,0 +1,45 @@ +use core::marker::PhantomData; + +use error_stack::{Result, ResultExt}; + +use crate::{ + error::{DeserializeError, VisitorError}, + Deserialize, Deserializer, Document, Reflection, Schema, Visitor, +}; + +struct PhantomDataVisitor(PhantomData); + +impl<'de, T: ?Sized> Visitor<'de> for PhantomDataVisitor { + type Value = PhantomData; + + fn expecting(&self) -> Document { + Self::Value::reflection() + } + + fn visit_none(self) -> Result { + Ok(PhantomData) + } + + fn visit_null(self) -> Result { + Ok(PhantomData) + } +} + +pub struct PhantomDataReflection; + +impl Reflection for PhantomDataReflection { + fn schema(_: &mut Document) -> Schema { + // TODO: this is also optional (none) + // currently we're unable to express that constraint (something for 0.2) + Schema::new("null") + } +} + +impl<'de, T: ?Sized> Deserialize<'de> for PhantomData { + type Reflection = PhantomDataReflection; + + fn deserialize>(de: D) -> Result { + de.deserialize_null(PhantomDataVisitor(PhantomData)) + .change_context(DeserializeError) + } +}