use crate::{registry, ContextSelectionSet, InputValueType, OutputValueType, Result, Type, Value}; use graphql_parser::Pos; 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 elem_value in values { result.push(InputValueType::parse(elem_value)?); } Some(result) } _ => Some(vec![InputValueType::parse(value)?]), } } } #[allow(clippy::ptr_arg)] #[async_trait::async_trait] impl OutputValueType for Vec { async fn resolve( value: &Self, ctx: &ContextSelectionSet<'_>, pos: Pos, ) -> Result { let mut futures = Vec::with_capacity(value.len()); for (idx, item) in value.iter().enumerate() { let ctx_idx = ctx.with_index(idx); futures.push(async move { OutputValueType::resolve(item, &ctx_idx, pos).await }); } Ok(futures::future::try_join_all(futures).await?.into()) } } 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<'_>, pos: Pos, ) -> Result { let mut futures = Vec::with_capacity(value.len()); for (idx, item) in (*value).iter().enumerate() { let ctx_idx = ctx.with_index(idx); futures.push(async move { OutputValueType::resolve(item, &ctx_idx, pos).await }); } Ok(futures::future::try_join_all(futures).await?.into()) } } #[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]"); } }