async-graphql/src/base.rs

116 lines
3.5 KiB
Rust
Raw Normal View History

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
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()
}
}
#[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
}
}