2020-03-06 15:58:43 +00:00
|
|
|
use crate::{registry, Context, ContextSelectionSet, Result};
|
|
|
|
use graphql_parser::query::{Field, Value};
|
2020-03-02 00:24:49 +00:00
|
|
|
use std::borrow::Cow;
|
2020-03-01 10:54:34 +00:00
|
|
|
|
2020-03-03 03:48:00 +00:00
|
|
|
pub trait GQLType {
|
|
|
|
fn type_name() -> Cow<'static, str>;
|
|
|
|
|
2020-03-03 11:15:18 +00:00
|
|
|
fn qualified_type_name() -> String {
|
|
|
|
format!("{}!", Self::type_name())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_type_info(registry: &mut registry::Registry) -> String;
|
2020-03-03 03:48:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait GQLInputValue: GQLType + Sized {
|
2020-03-04 02:38:07 +00:00
|
|
|
fn parse(value: &Value) -> Option<Self>;
|
2020-03-03 03:48:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
pub trait GQLOutputValue: GQLType {
|
2020-03-06 15:58:43 +00:00
|
|
|
async fn resolve(value: &Self, ctx: &ContextSelectionSet<'_>) -> Result<serde_json::Value>;
|
2020-03-03 03:48:00 +00:00
|
|
|
}
|
|
|
|
|
2020-03-06 15:58:43 +00:00
|
|
|
#[async_trait::async_trait]
|
2020-03-05 09:06:14 +00:00
|
|
|
pub trait GQLObject: GQLOutputValue {
|
|
|
|
fn is_empty() -> bool {
|
|
|
|
return false;
|
|
|
|
}
|
2020-03-06 15:58:43 +00:00
|
|
|
|
|
|
|
async fn resolve_field(&self, ctx: &Context<'_>, field: &Field) -> Result<serde_json::Value>;
|
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<()>;
|
2020-03-05 09:06:14 +00:00
|
|
|
}
|
2020-03-03 03:48:00 +00:00
|
|
|
|
|
|
|
pub trait GQLInputObject: GQLInputValue {}
|
|
|
|
|
2020-03-05 06:23:55 +00:00
|
|
|
pub trait GQLScalar: Sized + Send {
|
2020-03-01 10:54:34 +00:00
|
|
|
fn type_name() -> &'static str;
|
2020-03-03 11:15:18 +00:00
|
|
|
fn description() -> Option<&'static str> {
|
|
|
|
None
|
|
|
|
}
|
2020-03-04 02:38:07 +00:00
|
|
|
fn parse(value: &Value) -> Option<Self>;
|
2020-03-02 00:24:49 +00:00
|
|
|
fn to_json(&self) -> Result<serde_json::Value>;
|
2020-03-01 10:54:34 +00:00
|
|
|
}
|
|
|
|
|
2020-03-06 15:58:43 +00:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! impl_scalar {
|
|
|
|
($ty:ty) => {
|
|
|
|
impl crate::GQLType for $ty {
|
|
|
|
fn type_name() -> std::borrow::Cow<'static, str> {
|
|
|
|
std::borrow::Cow::Borrowed(<$ty as crate::GQLScalar>::type_name())
|
|
|
|
}
|
2020-03-03 03:48:00 +00:00
|
|
|
|
2020-03-06 15:58:43 +00:00
|
|
|
fn create_type_info(registry: &mut crate::registry::Registry) -> String {
|
|
|
|
registry.create_type::<$ty, _>(|_| crate::registry::Type::Scalar {
|
|
|
|
name: <$ty as crate::GQLScalar>::type_name().to_string(),
|
|
|
|
description: <$ty>::description(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2020-03-01 10:54:34 +00:00
|
|
|
|
2020-03-07 10:03:19 +00:00
|
|
|
impl crate::GQLType for &$ty {
|
|
|
|
fn type_name() -> std::borrow::Cow<'static, str> {
|
|
|
|
std::borrow::Cow::Borrowed(<$ty as crate::GQLScalar>::type_name())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_type_info(registry: &mut crate::registry::Registry) -> String {
|
|
|
|
registry.create_type::<$ty, _>(|_| crate::registry::Type::Scalar {
|
|
|
|
name: <$ty as crate::GQLScalar>::type_name().to_string(),
|
|
|
|
description: <$ty>::description(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-06 15:58:43 +00:00
|
|
|
impl crate::GQLInputValue for $ty {
|
|
|
|
fn parse(value: &crate::Value) -> Option<Self> {
|
|
|
|
<$ty as crate::GQLScalar>::parse(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
impl crate::GQLOutputValue for $ty {
|
|
|
|
async fn resolve(
|
|
|
|
value: &Self,
|
|
|
|
_: &crate::ContextSelectionSet<'_>,
|
|
|
|
) -> crate::Result<serde_json::Value> {
|
|
|
|
value.to_json()
|
|
|
|
}
|
|
|
|
}
|
2020-03-07 10:03:19 +00:00
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
impl crate::GQLOutputValue for &$ty {
|
|
|
|
async fn resolve(
|
|
|
|
value: &Self,
|
|
|
|
_: &crate::ContextSelectionSet<'_>,
|
|
|
|
) -> crate::Result<serde_json::Value> {
|
|
|
|
value.to_json()
|
|
|
|
}
|
|
|
|
}
|
2020-03-06 15:58:43 +00:00
|
|
|
};
|
2020-03-01 10:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
2020-03-06 15:58:43 +00:00
|
|
|
impl<T: GQLObject + Send + Sync> GQLOutputValue for T {
|
|
|
|
async fn resolve(value: &Self, ctx: &ContextSelectionSet<'_>) -> Result<serde_json::Value> {
|
2020-03-07 02:39:55 +00:00
|
|
|
let mut result = serde_json::Map::<String, serde_json::Value>::new();
|
|
|
|
crate::resolver::do_resolve(ctx, value, &mut result).await?;
|
|
|
|
Ok(result.into())
|
2020-03-01 10:54:34 +00:00
|
|
|
}
|
|
|
|
}
|