pub fn add_set<T: ContainerType + ?Sized>(
        &mut self,
        ctx: &ContextSelectionSet<'a>,
        root: &'a T,
    ) -> ServerResult<()> {
        for selection in &ctx.item.node.items {
            if ctx.is_skip(&selection.node.directives())? {
                continue;
            }

            match &selection.node {
                Selection::Field(field) => {
                    if field.node.name.node == "__typename" {
                        // Get the typename
                        let ctx_field = ctx.with_field(field);
                        let field_name = ctx_field.item.node.response_key().node.clone();
                        let typename = root.introspection_type_name().into_owned();

                        self.0.push(Box::pin(async move {
                            Ok((field_name, Value::String(typename)))
                        }));
                        continue;
                    }

                    if ctx.is_ifdef(&field.node.directives) {
                        if let Some(MetaType::Object { fields, .. }) =
                            ctx.schema_env.registry.types.get(T::type_name().as_ref())
                        {
                            if !fields.contains_key(field.node.name.node.as_str()) {
                                continue;
                            }
                        }
                    }

                    self.0.push(Box::pin({
                        let ctx = ctx.clone();
                        async move {
                            let ctx_field = ctx.with_field(field);
                            let field_name = ctx_field.item.node.response_key().node.clone();
                            let extensions = &ctx.query_env.extensions;

                            if extensions.is_empty() {
                                Ok((
                                    field_name,
                                    root.resolve_field(&ctx_field).await?.unwrap_or_default(),
                                ))
                            } else {
                                let type_name = T::type_name();
                                let resolve_info = ResolveInfo {
                                    path_node: ctx_field.path_node.as_ref().unwrap(),
                                    parent_type: &type_name,
                                    return_type: match ctx_field
                                        .schema_env
                                        .registry
                                        .types
                                        .get(type_name.as_ref())
                                        .and_then(|ty| {
                                            ty.field_by_name(field.node.name.node.as_str())
                                        })
                                        .map(|field| &field.ty)
                                    {
                                        Some(ty) => &ty,
                                        None => {
                                            return Err(ServerError::new(
                                                format!(
                                                    r#"Cannot query field "{}" on type "{}"."#,
                                                    field_name, type_name
                                                ),
                                                Some(ctx_field.item.pos),
                                            ));
                                        }
                                    },
                                    name: field.node.name.node.as_str(),
                                    alias: field
                                        .node
                                        .alias
                                        .as_ref()
                                        .map(|alias| alias.node.as_str()),
                                };

                                let resolve_fut = root.resolve_field(&ctx_field);
                                futures_util::pin_mut!(resolve_fut);
                                Ok((
                                    field_name,
                                    extensions
                                        .resolve(resolve_info, &mut resolve_fut)
                                        .await?
                                        .unwrap_or_default(),
                                ))
                            }
                        }
                    }));
                }
                selection => {
                    let (type_condition, selection_set) = match selection {
                        Selection::Field(_) => unreachable!(),
                        Selection::FragmentSpread(spread) => {
                            let fragment =
                                ctx.query_env.fragments.get(&spread.node.fragment_name.node);
                            let fragment = match fragment {
                                Some(fragment) => fragment,
                                None => {
                                    return Err(ServerError::new(
                                        format!(
                                            r#"Unknown fragment "{}"."#,
                                            spread.node.fragment_name.node
                                        ),
                                        Some(spread.pos),
                                    ));
                                }
                            };
                            (
                                Some(&fragment.node.type_condition),
                                &fragment.node.selection_set,
                            )
                        }
                        Selection::InlineFragment(fragment) => (
                            fragment.node.type_condition.as_ref(),
                            &fragment.node.selection_set,
                        ),
                    };
                    let type_condition =
                        type_condition.map(|condition| condition.node.on.node.as_str());

                    let introspection_type_name = root.introspection_type_name();

                    let applies_concrete_object = type_condition.map_or(false, |condition| {
                        introspection_type_name == condition
                            || ctx
                                .schema_env
                                .registry
                                .implements
                                .get(&*introspection_type_name)
                                .map_or(false, |interfaces| interfaces.contains(condition))
                    });
                    if applies_concrete_object {
                        root.collect_all_fields(&ctx.with_selection_set(selection_set), self)?;
                    } else if type_condition.map_or(true, |condition| T::type_name() == condition) {
                        // The fragment applies to an interface type.
                        self.add_set(&ctx.with_selection_set(selection_set), root)?;
                    }
                }
            }
        }
        Ok(())
    }
/// Add another set of fields to this set of fields using the given container.
Add another set of fields to this set of fields using the given container.
Add another set of fields to this set of fields using the given container .
pub fn add_set<T: ContainerType + ?Sized>(
        &mut self,
        ctx: &ContextSelectionSet<'a>,
        root: &'a T,
    ) -> ServerResult<()> {
        for selection in &ctx.item.node.items {
            if ctx.is_skip(&selection.node.directives())? {
                continue;
            }
            match &selection.node {
                Selection::Field(field) => {
                    if field.node.name.node == "__typename" {
                        // Get the typename
                        let ctx_field = ctx.with_field(field);
                        let field_name = ctx_field.item.node.response_key().node.clone();
                        let typename = root.introspection_type_name().into_owned();
                        self.0.push(Box::pin(async move {
                            Ok((field_name, Value::String(typename)))
                        }));
                        continue;
                    }
                    if ctx.is_ifdef(&field.node.directives) {
                        if let Some(MetaType::Object { fields, .. }) =
                            ctx.schema_env.registry.types.get(T::type_name().as_ref())
                        {
                            if !fields.contains_key(field.node.name.node.as_str()) {
                                continue;
                            }
                        }
                    }
                    self.0.push(Box::pin({
                        let ctx = ctx.clone();
                        async move {
                            let ctx_field = ctx.with_field(field);
                            let field_name = ctx_field.item.node.response_key().node.clone();
                            let extensions = &ctx.query_env.extensions;
                            if extensions.is_empty() {
                                Ok((
                                    field_name,
                                    root.resolve_field(&ctx_field).await?.unwrap_or_default(),
                                ))
                            } else {
                                let type_name = T::type_name();
                                let resolve_info = ResolveInfo {
                                    path_node: ctx_field.path_node.as_ref().unwrap(),
                                    parent_type: &type_name,
                                    return_type: match ctx_field
                                        .schema_env
                                        .registry
                                        .types
                                        .get(type_name.as_ref())
                                        .and_then(|ty| {
                                            ty.field_by_name(field.node.name.node.as_str())
                                        })
                                        .map(|field| &field.ty)
                                    {
                                        Some(ty) => &ty,
                                        None => {
                                            return Err(ServerError::new(
                                                format!(
                                                    r#"Cannot query field "{}" on type "{}"."#,
                                                    field_name, type_name
                                                ),
                                                Some(ctx_field.item.pos),
                                            ));
                                        }
                                    },
                                    name: field.node.name.node.as_str(),
                                    alias: field
                                        .node
                                        .alias
                                        .as_ref()
                                        .map(|alias| alias.node.as_str()),
                                };
                                let resolve_fut = root.resolve_field(&ctx_field);
                                futures_util::pin_mut!(resolve_fut);
                                Ok((
                                    field_name,
                                    extensions
                                        .resolve(resolve_info, &mut resolve_fut)
                                        .await?
                                        .unwrap_or_default(),
                                ))
                            }
                        }
                    }));
                }
                selection => {
                    let (type_condition, selection_set) = match selection {
                        Selection::Field(_) => unreachable!(),
                        Selection::FragmentSpread(spread) => {
                            let fragment =
                                ctx.query_env.fragments.get(&spread.node.fragment_name.node);
                            let fragment = match fragment {
                                Some(fragment) => fragment,
                                None => {
                                    return Err(ServerError::new(
                                        format!(
                                            r#"Unknown fragment "{}"."#,
                                            spread.node.fragment_name.node
                                        ),
                                        Some(spread.pos),
                                    ));
                                }
                            };
                            (
                                Some(&fragment.node.type_condition),
                                &fragment.node.selection_set,
                            )
                        }
                        Selection::InlineFragment(fragment) => (
                            fragment.node.type_condition.as_ref(),
                            &fragment.node.selection_set,
                        ),
                    };
                    let type_condition =
                        type_condition.map(|condition| condition.node.on.node.as_str());
                    let introspection_type_name = root.introspection_type_name();
                    let applies_concrete_object = type_condition.map_or(false, |condition| {
                        introspection_type_name == condition
                            || ctx
                                .schema_env
                                .registry
                                .implements
                                .get(&*introspection_type_name)
                                .map_or(false, |interfaces| interfaces.contains(condition))
                    });
                    if applies_concrete_object {
                        root.collect_all_fields(&ctx.with_selection_set(selection_set), self)?;
                    } else if type_condition.map_or(true, |condition| T::type_name() == condition) {
                        // The fragment applies to an interface type.
                        self.add_set(&ctx.with_selection_set(selection_set), root)?;
                    }
                }
            }
        }
        Ok(())
    }
pub fn add_set < T : ContainerType + ? Sized > ( & mut self , ctx : & ContextSelectionSet < ' a > , root : & ' a T , ) -> ServerResult < ( ) > { for selection in & ctx . item . node . items { if ctx . is_skip ( & selection . node . directives ( ) ) ? { continue ; } match & selection . node { Selection :: Field ( field ) => { if field . node . name . node == " " { // Get the typename let ctx_field = ctx . with_field ( field ) ; let field_name = ctx_field . item . node . response_key ( ) . node . clone ( ) ; let typename = root . introspection_type_name ( ) . into_owned ( ) ; self . 0 . push ( Box :: pin ( async move { Ok ( ( field_name , Value :: String ( typename ) ) ) } ) ) ; continue ; } if ctx . is_ifdef ( & field . node . directives ) { if let Some ( MetaType :: Object { fields , .. } ) = ctx . schema_env . registry . types . get ( T :: type_name ( ) . as_ref ( ) ) { if ! fields . contains_key ( field . node . name . node . as_str ( ) ) { continue ; } } } self . 0 . push ( Box :: pin ( { let ctx = ctx . clone ( ) ; async move { let ctx_field = ctx . with_field ( field ) ; let field_name = ctx_field . item . node . response_key ( ) . node . clone ( ) ; let extensions = & ctx . query_env . extensions ; if extensions . is_empty ( ) { Ok ( ( field_name , root . resolve_field ( & ctx_field ) . await ? . unwrap_or_default ( ) , ) ) } else { let type_name = T :: type_name ( ) ; let resolve_info = ResolveInfo { path_node : ctx_field . path_node . as_ref ( ) . unwrap ( ) , parent_type : & type_name , return_type : match ctx_field . schema_env . registry . types . get ( type_name . as_ref ( ) ) . and_then ( | ty | { ty . field_by_name ( field . node . name . node . as_str ( ) ) } ) . map ( | field | & field . ty ) { Some ( ty ) => & ty , None => { return Err ( ServerError :: new ( format ! ( r#"Cannot query field "{}" on type "{}"."# field_name type_name ) , Some ( ctx_field . item . pos ) , ) ) ; } } , name : field . node . name . node . as_str ( ) , alias : field . node . alias . as_ref ( ) . map ( | alias | alias . node . as_str ( ) ) , } ; let resolve_fut = root . resolve_field ( & ctx_field ) ; futures_util :: pin_mut ! ( resolve_fut ) ; Ok ( ( field_name , extensions . resolve ( resolve_info , & mut resolve_fut ) . await ? . unwrap_or_default ( ) , ) ) } } } ) ) ; } selection => { let ( type_condition , selection_set ) = match selection { Selection :: Field ( _ ) => unreachable ! ( ) , Selection :: FragmentSpread ( spread ) => { let fragment = ctx . query_env . fragments . get ( & spread . node . fragment_name . node ) ; let fragment = match fragment { Some ( fragment ) => fragment , None => { return Err ( ServerError :: new ( format ! ( r#"Unknown fragment "{}"."# spread node fragment_name node ) , Some ( spread . pos ) , ) ) ; } } ; ( Some ( & fragment . node . type_condition ) , & fragment . node . selection_set , ) } Selection :: InlineFragment ( fragment ) => ( fragment . node . type_condition . as_ref ( ) , & fragment . node . selection_set , ) , } ; let type_condition = type_condition . map ( | condition | condition . node . on . node . as_str ( ) ) ; let introspection_type_name = root . introspection_type_name ( ) ; let applies_concrete_object = type_condition . map_or ( false , | condition | { introspection_type_name == condition || ctx . schema_env . registry . implements . get ( & * introspection_type_name ) . map_or ( false , | interfaces | interfaces . contains ( condition ) ) } ) ; if applies_concrete_object { root . collect_all_fields ( & ctx . with_selection_set ( selection_set ) , self ) ? ; } else if type_condition . map_or ( true , | condition | T :: type_name ( ) == condition ) { // The fragment applies to an interface type. self . add_set ( & ctx . with_selection_set ( selection_set ) , root ) ? ; } } } } Ok ( ( ) ) }
Add another set of fields to this set of fields using the given container.
Add another set of fields to this set of fields using the given container .
&mut self
ctx
&ContextSelectionSet<'a>
root
&'a T
&mut self
ctx
&ContextSelectionSet<'a>
root
&'a T