nakago_async_graphql/
schema.rs

1use std::any::Any;
2
3use async_graphql::{ObjectType, Schema, SchemaBuilder, SubscriptionType};
4use derive_new::new;
5use nakago::{Inject, Tag};
6
7/// Initialize the GraphQL Schema and inject it with the given Tag
8#[derive(new)]
9pub struct Init<Query: Any, Mutation: Any, Subscription: Any> {
10    builder_tag: Option<&'static Tag<SchemaBuilder<Query, Mutation, Subscription>>>,
11    schema_tag: Option<&'static Tag<Schema<Query, Mutation, Subscription>>>,
12}
13
14// Implement manually rather than deriving, to avoid error messages for consumers like "the trait
15// `std::default::Default` is not implemented for `graphql::Query`"
16impl<Query: Any, Mutation: Any, Subscription: Any> Default for Init<Query, Mutation, Subscription> {
17    fn default() -> Self {
18        Self {
19            builder_tag: None,
20            schema_tag: None,
21        }
22    }
23}
24
25impl<Query: Any, Mutation: Any, Subscription: Any> Init<Query, Mutation, Subscription> {
26    /// Add a builder tag to the hook
27    pub fn with_builder_tag(
28        self,
29        tag: &'static Tag<SchemaBuilder<Query, Mutation, Subscription>>,
30    ) -> Self {
31        Self {
32            builder_tag: Some(tag),
33            ..self
34        }
35    }
36
37    /// Add a schema tag to the hook
38    pub fn with_schema_tag(self, tag: &'static Tag<Schema<Query, Mutation, Subscription>>) -> Self {
39        Self {
40            schema_tag: Some(tag),
41            ..self
42        }
43    }
44
45    /// Initialize the schema and inject it
46    pub async fn init(&self, inject: &Inject) -> nakago::Result<()>
47    where
48        Query: ObjectType + 'static,
49        Mutation: ObjectType + 'static,
50        Subscription: SubscriptionType + 'static,
51    {
52        let schema_builder = if let Some(tag) = self.builder_tag {
53            inject.consume_tag(tag).await?
54        } else {
55            inject
56                .consume::<SchemaBuilder<Query, Mutation, Subscription>>()
57                .await?
58        };
59
60        let schema = schema_builder.finish();
61
62        if let Some(tag) = self.schema_tag {
63            inject.inject_tag(tag, schema).await?;
64        } else {
65            inject.inject(schema).await?;
66        }
67
68        Ok(())
69    }
70}