use crate::parser::types::Field; use crate::{ registry, ContextSelectionSet, InputValueResult, InputValueType, OutputValueType, Positioned, Result, Type, Value, }; use std::borrow::Cow; impl Type for Option { fn type_name() -> Cow<'static, str> { T::type_name() } fn qualified_type_name() -> String { T::type_name().to_string() } fn create_type_info(registry: &mut registry::Registry) -> String { T::create_type_info(registry); T::type_name().to_string() } } impl InputValueType for Option { fn parse(value: Option) -> InputValueResult { match value.unwrap_or_default() { Value::Null => Ok(None), value => Ok(Some(T::parse(Some(value))?)), } } fn to_value(&self) -> Value { match self { Some(value) => value.to_value(), None => Value::Null, } } } #[async_trait::async_trait] impl OutputValueType for Option { async fn resolve( &self, ctx: &ContextSelectionSet<'_>, field: &Positioned, ) -> Result where { if let Some(inner) = self { OutputValueType::resolve(inner, ctx, field).await } else { Ok(serde_json::Value::Null) } } } #[cfg(test)] mod tests { use crate::Type; #[test] fn test_optional_type() { assert_eq!(Option::::type_name(), "Int"); assert_eq!(Option::::qualified_type_name(), "Int"); assert_eq!(&Option::::type_name(), "Int"); assert_eq!(&Option::::qualified_type_name(), "Int"); } }