2020-03-06 15:58:43 +00:00
|
|
|
use crate::model::{__Schema, __Type};
|
|
|
|
use crate::{
|
2020-03-07 02:39:55 +00:00
|
|
|
registry, Context, ContextSelectionSet, ErrorWithPosition, GQLObject, GQLOutputValue, GQLType,
|
|
|
|
QueryError, Result, Value,
|
2020-03-06 15:58:43 +00:00
|
|
|
};
|
|
|
|
use graphql_parser::query::Field;
|
2020-03-02 00:24:49 +00:00
|
|
|
use std::borrow::Cow;
|
|
|
|
|
2020-03-03 11:15:18 +00:00
|
|
|
pub struct QueryRoot<T> {
|
|
|
|
pub inner: T,
|
|
|
|
pub query_type: String,
|
2020-03-05 09:06:14 +00:00
|
|
|
pub mutation_type: Option<String>,
|
2020-03-03 11:15:18 +00:00
|
|
|
}
|
2020-03-02 00:24:49 +00:00
|
|
|
|
2020-03-03 03:48:00 +00:00
|
|
|
impl<T: GQLType> GQLType for QueryRoot<T> {
|
2020-03-02 00:24:49 +00:00
|
|
|
fn type_name() -> Cow<'static, str> {
|
2020-03-03 03:48:00 +00:00
|
|
|
T::type_name()
|
|
|
|
}
|
|
|
|
|
2020-03-03 11:15:18 +00:00
|
|
|
fn create_type_info(registry: &mut registry::Registry) -> String {
|
2020-03-03 03:48:00 +00:00
|
|
|
T::create_type_info(registry)
|
2020-03-02 00:24:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
2020-03-06 15:58:43 +00:00
|
|
|
impl<T: GQLObject + Send + Sync> GQLObject for QueryRoot<T> {
|
|
|
|
async fn resolve_field(&self, ctx: &Context<'_>, field: &Field) -> Result<serde_json::Value> {
|
|
|
|
if field.name.as_str() == "__schema" {
|
|
|
|
let ctx_obj = ctx.with_item(&field.selection_set);
|
|
|
|
return GQLOutputValue::resolve(
|
|
|
|
&__Schema {
|
|
|
|
registry: &ctx.registry,
|
|
|
|
query_type: &self.query_type,
|
|
|
|
mutation_type: self.mutation_type.as_deref(),
|
|
|
|
},
|
|
|
|
&ctx_obj,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.map_err(|err| err.with_position(field.position).into());
|
|
|
|
} else if field.name.as_str() == "__type" {
|
|
|
|
let type_name: String = ctx.param_value("name", || Value::Null)?;
|
|
|
|
let ctx_obj = ctx.with_item(&field.selection_set);
|
|
|
|
return GQLOutputValue::resolve(
|
|
|
|
&ctx.registry
|
|
|
|
.types
|
|
|
|
.get(&type_name)
|
|
|
|
.map(|ty| __Type::new_simple(ctx.registry, ty)),
|
|
|
|
&ctx_obj,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.map_err(|err| err.with_position(field.position).into());
|
2020-03-02 00:24:49 +00:00
|
|
|
}
|
2020-03-03 11:15:18 +00:00
|
|
|
|
2020-03-06 15:58:43 +00:00
|
|
|
return self.inner.resolve_field(ctx, field).await;
|
2020-03-02 00:24:49 +00:00
|
|
|
}
|
2020-03-07 02:39:55 +00:00
|
|
|
|
|
|
|
async fn resolve_inline_fragment(
|
|
|
|
&self,
|
|
|
|
name: &str,
|
|
|
|
_ctx: &ContextSelectionSet<'_>,
|
|
|
|
_result: &mut serde_json::Map<String, serde_json::Value>,
|
|
|
|
) -> Result<()> {
|
|
|
|
anyhow::bail!(QueryError::UnrecognizedInlineFragment {
|
|
|
|
object: T::type_name().to_string(),
|
|
|
|
name: name.to_string(),
|
|
|
|
});
|
|
|
|
}
|
2020-03-02 00:24:49 +00:00
|
|
|
}
|