rusty_gql/
query_root.rs

1use crate::{
2    error::GqlError,
3    types::{__Type, build_schema_introspection},
4    CollectFields, Context, FieldResolver, GqlValue, ResolverResult, SelectionSetResolver,
5};
6
7pub struct QueryRoot<T> {
8    pub query: T,
9}
10
11#[async_trait::async_trait]
12impl<T: SelectionSetResolver> FieldResolver for QueryRoot<T> {
13    async fn resolve_field(&self, ctx: &Context<'_>) -> ResolverResult<Option<GqlValue>> {
14        if ctx.item.name == "__schema" {
15            let ctx_selection_set = ctx.with_selection_set(&ctx.item.selection_set);
16            let schema_intro = build_schema_introspection(ctx.schema);
17            return schema_intro
18                .resolve_selection_set(&ctx_selection_set)
19                .await
20                .map(Some);
21        } else if ctx.item.name == "__type" {
22            let type_name = ctx.get_arg_value::<String>("name")?;
23            let ctx_selection_set = ctx.with_selection_set(&ctx.item.selection_set);
24            let ty = ctx_selection_set
25                .schema
26                .type_definitions
27                .get(&type_name)
28                .map(|ty| __Type::from_type_definition(ctx_selection_set.schema, ty));
29            match ty {
30                Some(intro_ty) => intro_ty
31                    .resolve_selection_set(&ctx_selection_set)
32                    .await
33                    .map(Some),
34                None => Err(GqlError::new(format!("{} is not defined", type_name), None)),
35            }
36        } else {
37            self.query.resolve_field(ctx).await
38        }
39    }
40    fn type_name() -> String {
41        "Query".to_string()
42    }
43}
44
45impl<T: SelectionSetResolver> CollectFields for QueryRoot<T> {}
46
47#[async_trait::async_trait]
48impl<T: SelectionSetResolver> SelectionSetResolver for QueryRoot<T> {
49    async fn resolve_selection_set(
50        &self,
51        ctx: &crate::SelectionSetContext<'_>,
52    ) -> ResolverResult<GqlValue> {
53        self.query.resolve_selection_set(ctx).await
54    }
55}