use crate::{ registry, ContextSelectionSet, InputValueType, JsonWriter, OutputValueType, Result, Type, Value, }; use std::borrow::Cow; impl Type for Vec { fn type_name() -> Cow<'static, str> { Cow::Owned(format!("[{}]", T::qualified_type_name())) } fn qualified_type_name() -> String { format!("[{}]!", T::qualified_type_name()) } fn create_type_info(registry: &mut registry::Registry) -> String { T::create_type_info(registry); Self::qualified_type_name() } } impl InputValueType for Vec { fn parse(value: &Value) -> Option { match value { Value::List(values) => { let mut result = Vec::new(); for value in values { result.push(InputValueType::parse(value)?); } Some(result) } _ => None, } } } #[allow(clippy::ptr_arg)] #[async_trait::async_trait] impl OutputValueType for Vec { async fn resolve( value: &Self, ctx: &ContextSelectionSet<'_>, w: &mut JsonWriter, ) -> Result<()> { w.begin_array(); for item in value { w.begin_array_value(); OutputValueType::resolve(item, &ctx, w).await?; w.end_array_value(); } w.end_array(); Ok(()) } } impl Type for &[T] { fn type_name() -> Cow<'static, str> { Cow::Owned(format!("[{}]", T::type_name())) } fn create_type_info(registry: &mut registry::Registry) -> String { T::create_type_info(registry) } } #[async_trait::async_trait] impl OutputValueType for &[T] { async fn resolve( value: &Self, ctx: &ContextSelectionSet<'_>, w: &mut JsonWriter, ) -> Result<()> { w.begin_array(); for item in value.iter() { w.begin_array_value(); OutputValueType::resolve(item, &ctx, w).await?; w.end_array_value(); } w.end_array(); Ok(()) } } #[cfg(test)] mod tests { use crate::Type; #[test] fn test_list_type() { assert_eq!(Vec::::type_name(), "[Int!]"); assert_eq!(Vec::>::type_name(), "[Int]"); assert_eq!(Option::>>::type_name(), "[Int]"); assert_eq!(Vec::::qualified_type_name(), "[Int!]!"); assert_eq!(Vec::>::qualified_type_name(), "[Int]!"); assert_eq!(Option::>>::qualified_type_name(), "[Int]"); } }