async_graphql/types/external/
optional.rs1use std::borrow::Cow;
2
3use crate::{
4 parser::types::Field, registry, ContextSelectionSet, InputType, InputValueError,
5 InputValueResult, OutputType, Positioned, ServerResult, Value,
6};
7
8impl<T: InputType> InputType for Option<T> {
9 type RawValueType = T::RawValueType;
10
11 fn type_name() -> Cow<'static, str> {
12 T::type_name()
13 }
14
15 fn qualified_type_name() -> String {
16 T::type_name().to_string()
17 }
18
19 fn create_type_info(registry: &mut registry::Registry) -> String {
20 T::create_type_info(registry);
21 T::type_name().to_string()
22 }
23
24 fn parse(value: Option<Value>) -> InputValueResult<Self> {
25 match value.unwrap_or_default() {
26 Value::Null => Ok(None),
27 value => Ok(Some(
28 T::parse(Some(value)).map_err(InputValueError::propagate)?,
29 )),
30 }
31 }
32
33 fn to_value(&self) -> Value {
34 match self {
35 Some(value) => value.to_value(),
36 None => Value::Null,
37 }
38 }
39
40 fn as_raw_value(&self) -> Option<&Self::RawValueType> {
41 match self {
42 Some(value) => value.as_raw_value(),
43 None => None,
44 }
45 }
46}
47
48#[cfg_attr(feature = "boxed-trait", async_trait::async_trait)]
49impl<T: OutputType + Sync> OutputType for Option<T> {
50 fn type_name() -> Cow<'static, str> {
51 T::type_name()
52 }
53
54 fn qualified_type_name() -> String {
55 T::type_name().to_string()
56 }
57
58 fn create_type_info(registry: &mut registry::Registry) -> String {
59 T::create_type_info(registry);
60 T::type_name().to_string()
61 }
62
63 async fn resolve(
64 &self,
65 ctx: &ContextSelectionSet<'_>,
66 field: &Positioned<Field>,
67 ) -> ServerResult<Value> {
68 if let Some(inner) = self {
69 match OutputType::resolve(inner, ctx, field).await {
70 Ok(value) => Ok(value),
71 Err(err) => {
72 ctx.add_error(err);
73 Ok(Value::Null)
74 }
75 }
76 } else {
77 Ok(Value::Null)
78 }
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use crate::InputType;
85
86 #[test]
87 fn test_optional_type() {
88 assert_eq!(Option::<i32>::type_name(), "Int");
89 assert_eq!(Option::<i32>::qualified_type_name(), "Int");
90 assert_eq!(&Option::<i32>::type_name(), "Int");
91 assert_eq!(&Option::<i32>::qualified_type_name(), "Int");
92 }
93}