add InputObject
This commit is contained in:
parent
5030a28361
commit
b62abdcd83
|
@ -1,12 +1,9 @@
|
||||||
use crate::args;
|
use crate::args;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::Span;
|
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{Data, DeriveInput, Error, Ident, Result};
|
use syn::{Data, DeriveInput, Error, Result};
|
||||||
|
|
||||||
pub fn generate(object_args: &args::Object, input: &DeriveInput) -> Result<TokenStream> {
|
pub fn generate(object_args: &args::Object, input: &DeriveInput) -> Result<TokenStream> {
|
||||||
let attrs = &input.attrs;
|
|
||||||
let vis = &input.vis;
|
|
||||||
let ident = &input.ident;
|
let ident = &input.ident;
|
||||||
let s = match &input.data {
|
let s = match &input.data {
|
||||||
Data::Struct(s) => s,
|
Data::Struct(s) => s,
|
||||||
|
@ -18,23 +15,44 @@ pub fn generate(object_args: &args::Object, input: &DeriveInput) -> Result<Token
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| ident.to_string());
|
.unwrap_or_else(|| ident.to_string());
|
||||||
|
|
||||||
|
let mut get_fields = Vec::new();
|
||||||
|
let mut fields = Vec::new();
|
||||||
for field in &s.fields {
|
for field in &s.fields {
|
||||||
let field_args = args::Field::parse(&field.attrs)?;
|
let field_args = args::InputField::parse(&field.attrs)?;
|
||||||
let ident = field.ident.as_ref().unwrap();
|
let ident = field.ident.as_ref().unwrap();
|
||||||
|
let ty = &field.ty;
|
||||||
|
let name = field_args.name.unwrap_or_else(|| ident.to_string());
|
||||||
|
get_fields.push(quote! {
|
||||||
|
let #ident:#ty = async_graphql::GQLInputValue::parse(obj.remove(#name).unwrap_or(async_graphql::Value::Null))?;
|
||||||
|
});
|
||||||
|
fields.push(ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#input
|
#input
|
||||||
|
|
||||||
impl async_graphql::Type for #ident {
|
impl async_graphql::GQLType for #ident {
|
||||||
fn type_name() -> String {
|
fn type_name() -> String {
|
||||||
#gql_typename.to_string()
|
#gql_typename.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl async_graphql::GQLInputObject for #ident {
|
impl async_graphql::GQLInputValue for #ident {
|
||||||
|
fn parse(value: async_graphql::Value) -> async_graphql::Result<Self> {
|
||||||
|
if let async_graphql::Value::Object(mut obj) = value {
|
||||||
|
#(#get_fields)*
|
||||||
|
Ok(Self { #(#fields),* })
|
||||||
|
} else {
|
||||||
|
Err(async_graphql::QueryError::ExpectedType {
|
||||||
|
expect: Self::type_name(),
|
||||||
|
actual: value,
|
||||||
|
}.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl async_graphql::GQLInputObject for #ident {}
|
||||||
};
|
};
|
||||||
|
println!("{}", expanded.to_string());
|
||||||
Ok(expanded.into())
|
Ok(expanded.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,10 +91,10 @@ pub fn generate(object_args: &args::Object, input: &DeriveInput) -> Result<Token
|
||||||
#[async_graphql::async_trait::async_trait]
|
#[async_graphql::async_trait::async_trait]
|
||||||
impl async_graphql::GQLOutputValue for #ident {
|
impl async_graphql::GQLOutputValue for #ident {
|
||||||
async fn resolve(self, ctx: &async_graphql::ContextSelectionSet<'_>) -> async_graphql::Result<async_graphql::serde_json::Value> {
|
async fn resolve(self, ctx: &async_graphql::ContextSelectionSet<'_>) -> async_graphql::Result<async_graphql::serde_json::Value> {
|
||||||
use async_graphql::GQLErrorWithPosition;
|
use async_graphql::ErrorWithPosition;
|
||||||
|
|
||||||
if ctx.items.is_empty() {
|
if ctx.items.is_empty() {
|
||||||
async_graphql::anyhow::bail!(async_graphql::GQLQueryError::MustHaveSubFields {
|
async_graphql::anyhow::bail!(async_graphql::QueryError::MustHaveSubFields {
|
||||||
object: #gql_typename,
|
object: #gql_typename,
|
||||||
}.with_position(ctx.span.0));
|
}.with_position(ctx.span.0));
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ pub fn generate(object_args: &args::Object, input: &DeriveInput) -> Result<Token
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#(#resolvers)*
|
#(#resolvers)*
|
||||||
async_graphql::anyhow::bail!(async_graphql::GQLQueryError::FieldNotFound {
|
async_graphql::anyhow::bail!(async_graphql::QueryError::FieldNotFound {
|
||||||
field_name: field.name.clone(),
|
field_name: field.name.clone(),
|
||||||
object: #gql_typename,
|
object: #gql_typename,
|
||||||
}.with_position(field.position));
|
}.with_position(field.position));
|
||||||
|
|
|
@ -6,6 +6,12 @@ enum MyEnum {
|
||||||
B,
|
B,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[async_graphql::InputObject]
|
||||||
|
struct MyInputObj {
|
||||||
|
a: i32,
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
#[async_graphql::Object(name = "haha", desc = "hehe")]
|
#[async_graphql::Object(name = "haha", desc = "hehe")]
|
||||||
struct MyObj {
|
struct MyObj {
|
||||||
#[field(
|
#[field(
|
||||||
|
@ -22,6 +28,9 @@ struct MyObj {
|
||||||
#[field(arg(name = "input", type = "MyEnum"))]
|
#[field(arg(name = "input", type = "MyEnum"))]
|
||||||
c: MyEnum,
|
c: MyEnum,
|
||||||
|
|
||||||
|
#[field(arg(name = "input", type = "MyInputObj"))]
|
||||||
|
d: i32,
|
||||||
|
|
||||||
#[field]
|
#[field]
|
||||||
child: ChildObj,
|
child: ChildObj,
|
||||||
}
|
}
|
||||||
|
@ -46,6 +55,10 @@ impl MyObjFields for MyObj {
|
||||||
Ok(input)
|
Ok(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn d(&self, ctx: &ContextField<'_>, input: MyInputObj) -> Result<i32> {
|
||||||
|
Ok(input.a + input.b)
|
||||||
|
}
|
||||||
|
|
||||||
async fn child(&self, ctx: &ContextField<'_>) -> async_graphql::Result<ChildObj> {
|
async fn child(&self, ctx: &ContextField<'_>) -> async_graphql::Result<ChildObj> {
|
||||||
Ok(ChildObj { value: 10.0 })
|
Ok(ChildObj { value: 10.0 })
|
||||||
}
|
}
|
||||||
|
@ -60,9 +73,13 @@ impl ChildObjFields for ChildObj {
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let res = GQLQueryBuilder::new(MyObj { a: 10 }, GQLEmptyMutation, "{ b c(input:B) }")
|
let res = QueryBuilder::new(
|
||||||
.execute()
|
MyObj { a: 10 },
|
||||||
.await
|
GQLEmptyMutation,
|
||||||
.unwrap();
|
"{ b c(input:B) d(input:{a:10 b:20}) }",
|
||||||
|
)
|
||||||
|
.execute()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
serde_json::to_writer_pretty(std::io::stdout(), &res).unwrap();
|
serde_json::to_writer_pretty(std::io::stdout(), &res).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{GQLInputValue, Result};
|
use crate::{ErrorWithPosition, GQLInputValue, QueryError, Result};
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use graphql_parser::query::{Field, SelectionSet, Value};
|
use graphql_parser::query::{Field, SelectionSet, Value};
|
||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
|
@ -80,6 +80,26 @@ impl<'a> Context<'a, &'a Field> {
|
||||||
.map(|(_, v)| v)
|
.map(|(_, v)| v)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or(Value::Null);
|
.unwrap_or(Value::Null);
|
||||||
GQLInputValue::parse(value)
|
let value = match (value, &self.variables) {
|
||||||
|
(Value::Variable(name), Some(vars)) => match vars.get(&name).cloned() {
|
||||||
|
Some(value) => value,
|
||||||
|
None => {
|
||||||
|
return Err(QueryError::VarNotDefined {
|
||||||
|
var_name: name.clone(),
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(Value::Variable(name), None) => {
|
||||||
|
return Err(QueryError::VarNotDefined {
|
||||||
|
var_name: name.clone(),
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
(value, _) => value,
|
||||||
|
};
|
||||||
|
let res =
|
||||||
|
GQLInputValue::parse(value).map_err(|err| err.with_position(self.item.position))?;
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{GQLQueryError, GQLScalar, Result, Value};
|
use crate::{QueryError, Scalar, Result, Value};
|
||||||
use chrono::{DateTime, TimeZone, Utc};
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
|
||||||
impl GQLScalar for DateTime<Utc> {
|
impl Scalar for DateTime<Utc> {
|
||||||
fn type_name() -> &'static str {
|
fn type_name() -> &'static str {
|
||||||
"DateTime"
|
"DateTime"
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ impl GQLScalar for DateTime<Utc> {
|
||||||
match value {
|
match value {
|
||||||
Value::String(s) => Ok(Utc.datetime_from_str(&s, "%+")?),
|
Value::String(s) => Ok(Utc.datetime_from_str(&s, "%+")?),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: Self::type_name().to_string(),
|
expect: Self::type_name().to_string(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{GQLQueryError, GQLType, Result};
|
use crate::{QueryError, GQLType, Result};
|
||||||
use graphql_parser::query::Value;
|
use graphql_parser::query::Value;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -22,14 +22,14 @@ pub trait GQLEnum: GQLType + Sized + Eq + Send + Copy + Sized + 'static {
|
||||||
return Ok(item.value);
|
return Ok(item.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(GQLQueryError::InvalidEnumValue {
|
Err(QueryError::InvalidEnumValue {
|
||||||
enum_type: Self::type_name(),
|
enum_type: Self::type_name(),
|
||||||
value: s,
|
value: s,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: Self::type_name(),
|
expect: Self::type_name(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
|
|
33
src/error.rs
33
src/error.rs
|
@ -5,10 +5,10 @@ use std::fmt::{Debug, Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
pub struct GQLQueryParseError(pub(crate) String);
|
pub struct QueryParseError(pub(crate) String);
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum GQLQueryError {
|
pub enum QueryError {
|
||||||
#[error("Not supported.")]
|
#[error("Not supported.")]
|
||||||
NotSupported,
|
NotSupported,
|
||||||
|
|
||||||
|
@ -30,20 +30,29 @@ pub enum GQLQueryError {
|
||||||
#[error("Schema is not configured for mutations.")]
|
#[error("Schema is not configured for mutations.")]
|
||||||
NotConfiguredMutations,
|
NotConfiguredMutations,
|
||||||
|
|
||||||
#[error("Invalid value for enum \"{enum_type}\"")]
|
#[error("Invalid value for enum \"{enum_type}\".")]
|
||||||
InvalidEnumValue { enum_type: String, value: String },
|
InvalidEnumValue { enum_type: String, value: String },
|
||||||
|
|
||||||
|
#[error("Required field \"{field_name}\" for InputObject \"{object}\" does not exist.")]
|
||||||
|
RequiredField {
|
||||||
|
field_name: String,
|
||||||
|
object: &'static str,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[error("Variable \"${var_name}\" is not defined")]
|
||||||
|
VarNotDefined { var_name: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GQLErrorWithPosition {
|
pub trait ErrorWithPosition {
|
||||||
type Result;
|
type Result;
|
||||||
fn with_position(self, position: Pos) -> GQLPositionError;
|
fn with_position(self, position: Pos) -> PositionError;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<Error>> GQLErrorWithPosition for T {
|
impl<T: Into<Error>> ErrorWithPosition for T {
|
||||||
type Result = GQLPositionError;
|
type Result = PositionError;
|
||||||
|
|
||||||
fn with_position(self, position: Pos) -> GQLPositionError {
|
fn with_position(self, position: Pos) -> PositionError {
|
||||||
GQLPositionError {
|
PositionError {
|
||||||
position,
|
position,
|
||||||
inner: self.into(),
|
inner: self.into(),
|
||||||
}
|
}
|
||||||
|
@ -51,12 +60,12 @@ impl<T: Into<Error>> GQLErrorWithPosition for T {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub struct GQLPositionError {
|
pub struct PositionError {
|
||||||
pub position: Pos,
|
pub position: Pos,
|
||||||
pub inner: Error,
|
pub inner: Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GQLPositionError {
|
impl PositionError {
|
||||||
pub fn new(position: Pos, inner: Error) -> Self {
|
pub fn new(position: Pos, inner: Error) -> Self {
|
||||||
Self { position, inner }
|
Self { position, inner }
|
||||||
}
|
}
|
||||||
|
@ -66,7 +75,7 @@ impl GQLPositionError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for GQLPositionError {
|
impl Display for PositionError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
|
|
@ -22,14 +22,16 @@ pub use serde_json;
|
||||||
|
|
||||||
pub use async_graphql_derive::{Enum, InputObject, Object};
|
pub use async_graphql_derive::{Enum, InputObject, Object};
|
||||||
pub use context::{Context, ContextField, ContextSelectionSet, Data, Variables};
|
pub use context::{Context, ContextField, ContextSelectionSet, Data, Variables};
|
||||||
pub use error::{GQLErrorWithPosition, GQLPositionError, GQLQueryError, GQLQueryParseError};
|
pub use error::{ErrorWithPosition, PositionError, QueryError, QueryParseError};
|
||||||
pub use graphql_parser::query::Value;
|
pub use graphql_parser::query::Value;
|
||||||
pub use query::GQLQueryBuilder;
|
pub use query::QueryBuilder;
|
||||||
|
pub use scalar::Scalar;
|
||||||
|
|
||||||
|
// internal types
|
||||||
pub use r#enum::{GQLEnum, GQLEnumItem};
|
pub use r#enum::{GQLEnum, GQLEnumItem};
|
||||||
pub use r#type::{
|
pub use r#type::{
|
||||||
GQLEmptyMutation, GQLInputObject, GQLInputValue, GQLObject, GQLOutputValue, GQLType,
|
GQLEmptyMutation, GQLInputObject, GQLInputValue, GQLObject, GQLOutputValue, GQLType,
|
||||||
};
|
};
|
||||||
pub use scalar::GQLScalar;
|
|
||||||
|
|
||||||
pub type Result<T> = anyhow::Result<T>;
|
pub type Result<T> = anyhow::Result<T>;
|
||||||
pub type Error = anyhow::Error;
|
pub type Error = anyhow::Error;
|
||||||
|
|
20
src/query.rs
20
src/query.rs
|
@ -1,11 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Context, Data, GQLErrorWithPosition, GQLObject, GQLQueryError, GQLQueryParseError, Result,
|
Context, Data, ErrorWithPosition, GQLObject, QueryError, QueryParseError, Result,
|
||||||
Variables,
|
Variables,
|
||||||
};
|
};
|
||||||
use graphql_parser::parse_query;
|
use graphql_parser::parse_query;
|
||||||
use graphql_parser::query::{Definition, OperationDefinition};
|
use graphql_parser::query::{Definition, OperationDefinition};
|
||||||
|
|
||||||
pub struct GQLQueryBuilder<'a, Query, Mutation> {
|
pub struct QueryBuilder<'a, Query, Mutation> {
|
||||||
query: Query,
|
query: Query,
|
||||||
mutation: Mutation,
|
mutation: Mutation,
|
||||||
query_source: &'a str,
|
query_source: &'a str,
|
||||||
|
@ -14,7 +14,7 @@ pub struct GQLQueryBuilder<'a, Query, Mutation> {
|
||||||
data: Option<&'a Data>,
|
data: Option<&'a Data>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Query, Mutation> GQLQueryBuilder<'a, Query, Mutation> {
|
impl<'a, Query, Mutation> QueryBuilder<'a, Query, Mutation> {
|
||||||
pub fn new(query: Query, mutation: Mutation, query_source: &'a str) -> Self {
|
pub fn new(query: Query, mutation: Mutation, query_source: &'a str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
query,
|
query,
|
||||||
|
@ -27,21 +27,21 @@ impl<'a, Query, Mutation> GQLQueryBuilder<'a, Query, Mutation> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn operator_name(self, name: &'a str) -> Self {
|
pub fn operator_name(self, name: &'a str) -> Self {
|
||||||
GQLQueryBuilder {
|
QueryBuilder {
|
||||||
operation_name: Some(name),
|
operation_name: Some(name),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variables(self, vars: &'a Variables) -> Self {
|
pub fn variables(self, vars: &'a Variables) -> Self {
|
||||||
GQLQueryBuilder {
|
QueryBuilder {
|
||||||
variables: Some(vars),
|
variables: Some(vars),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(self, data: &'a Data) -> Self {
|
pub fn data(self, data: &'a Data) -> Self {
|
||||||
GQLQueryBuilder {
|
QueryBuilder {
|
||||||
data: Some(data),
|
data: Some(data),
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ impl<'a, Query, Mutation> GQLQueryBuilder<'a, Query, Mutation> {
|
||||||
Mutation: GQLObject,
|
Mutation: GQLObject,
|
||||||
{
|
{
|
||||||
let document =
|
let document =
|
||||||
parse_query(self.query_source).map_err(|err| GQLQueryParseError(err.to_string()))?;
|
parse_query(self.query_source).map_err(|err| QueryParseError(err.to_string()))?;
|
||||||
|
|
||||||
for definition in &document.definitions {
|
for definition in &document.definitions {
|
||||||
match definition {
|
match definition {
|
||||||
|
@ -92,16 +92,16 @@ impl<'a, Query, Mutation> GQLQueryBuilder<'a, Query, Mutation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Definition::Operation(OperationDefinition::Subscription(subscription)) => {
|
Definition::Operation(OperationDefinition::Subscription(subscription)) => {
|
||||||
anyhow::bail!(GQLQueryError::NotSupported.with_position(subscription.position));
|
anyhow::bail!(QueryError::NotSupported.with_position(subscription.position));
|
||||||
}
|
}
|
||||||
Definition::Fragment(fragment) => {
|
Definition::Fragment(fragment) => {
|
||||||
anyhow::bail!(GQLQueryError::NotSupported.with_position(fragment.position));
|
anyhow::bail!(QueryError::NotSupported.with_position(fragment.position));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(operation_name) = self.operation_name {
|
if let Some(operation_name) = self.operation_name {
|
||||||
anyhow::bail!(GQLQueryError::UnknownOperationNamed {
|
anyhow::bail!(QueryError::UnknownOperationNamed {
|
||||||
name: operation_name.to_string()
|
name: operation_name.to_string()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
use crate::r#type::{GQLInputValue, GQLOutputValue, GQLType};
|
use crate::r#type::{GQLInputValue, GQLOutputValue, GQLType};
|
||||||
use crate::{ContextSelectionSet, GQLQueryError, Result};
|
use crate::{ContextSelectionSet, QueryError, Result};
|
||||||
use graphql_parser::query::Value;
|
use graphql_parser::query::Value;
|
||||||
|
|
||||||
pub trait GQLScalar: Sized + Send {
|
pub trait Scalar: Sized + Send {
|
||||||
fn type_name() -> &'static str;
|
fn type_name() -> &'static str;
|
||||||
fn parse(value: Value) -> Result<Self>;
|
fn parse(value: Value) -> Result<Self>;
|
||||||
fn into_json(self) -> Result<serde_json::Value>;
|
fn into_json(self) -> Result<serde_json::Value>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GQLScalar> GQLType for T {
|
impl<T: Scalar> GQLType for T {
|
||||||
fn type_name() -> String {
|
fn type_name() -> String {
|
||||||
T::type_name().to_string()
|
T::type_name().to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: GQLScalar> GQLInputValue for T {
|
impl<T: Scalar> GQLInputValue for T {
|
||||||
fn parse(value: Value) -> Result<Self> {
|
fn parse(value: Value) -> Result<Self> {
|
||||||
T::parse(value)
|
T::parse(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<T: GQLScalar> GQLOutputValue for T {
|
impl<T: Scalar> GQLOutputValue for T {
|
||||||
async fn resolve(self, _: &ContextSelectionSet<'_>) -> Result<serde_json::Value> {
|
async fn resolve(self, _: &ContextSelectionSet<'_>) -> Result<serde_json::Value> {
|
||||||
T::into_json(self)
|
T::into_json(self)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ impl<T: GQLScalar> GQLOutputValue for T {
|
||||||
macro_rules! impl_integer_scalars {
|
macro_rules! impl_integer_scalars {
|
||||||
($($ty:ty),*) => {
|
($($ty:ty),*) => {
|
||||||
$(
|
$(
|
||||||
impl GQLScalar for $ty {
|
impl Scalar for $ty {
|
||||||
fn type_name() -> &'static str {
|
fn type_name() -> &'static str {
|
||||||
"Int!"
|
"Int!"
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ macro_rules! impl_integer_scalars {
|
||||||
match value {
|
match value {
|
||||||
Value::Int(n) => Ok(n.as_i64().unwrap() as Self),
|
Value::Int(n) => Ok(n.as_i64().unwrap() as Self),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: <Self as GQLScalar>::type_name().to_string(),
|
expect: <Self as Scalar>::type_name().to_string(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
|
@ -61,7 +61,7 @@ impl_integer_scalars!(i8, i16, i32, i64, u8, u16, u32, u64);
|
||||||
macro_rules! impl_float_scalars {
|
macro_rules! impl_float_scalars {
|
||||||
($($ty:ty),*) => {
|
($($ty:ty),*) => {
|
||||||
$(
|
$(
|
||||||
impl GQLScalar for $ty {
|
impl Scalar for $ty {
|
||||||
fn type_name() -> &'static str {
|
fn type_name() -> &'static str {
|
||||||
"Float!"
|
"Float!"
|
||||||
}
|
}
|
||||||
|
@ -71,8 +71,8 @@ macro_rules! impl_float_scalars {
|
||||||
Value::Int(n) => Ok(n.as_i64().unwrap() as Self),
|
Value::Int(n) => Ok(n.as_i64().unwrap() as Self),
|
||||||
Value::Float(n) => Ok(n as Self),
|
Value::Float(n) => Ok(n as Self),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: <Self as GQLScalar>::type_name().to_string(),
|
expect: <Self as Scalar>::type_name().to_string(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
|
@ -90,7 +90,7 @@ macro_rules! impl_float_scalars {
|
||||||
|
|
||||||
impl_float_scalars!(f32, f64);
|
impl_float_scalars!(f32, f64);
|
||||||
|
|
||||||
impl GQLScalar for String {
|
impl Scalar for String {
|
||||||
fn type_name() -> &'static str {
|
fn type_name() -> &'static str {
|
||||||
"String!"
|
"String!"
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,8 @@ impl GQLScalar for String {
|
||||||
match value {
|
match value {
|
||||||
Value::String(s) => Ok(s),
|
Value::String(s) => Ok(s),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: <Self as GQLScalar>::type_name().to_string(),
|
expect: <Self as Scalar>::type_name().to_string(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
|
@ -113,7 +113,7 @@ impl GQLScalar for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GQLScalar for bool {
|
impl Scalar for bool {
|
||||||
fn type_name() -> &'static str {
|
fn type_name() -> &'static str {
|
||||||
"Boolean!"
|
"Boolean!"
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,8 @@ impl GQLScalar for bool {
|
||||||
match value {
|
match value {
|
||||||
Value::Boolean(n) => Ok(n),
|
Value::Boolean(n) => Ok(n),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: <Self as GQLScalar>::type_name().to_string(),
|
expect: <Self as Scalar>::type_name().to_string(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
.into())
|
.into())
|
||||||
|
|
10
src/type.rs
10
src/type.rs
|
@ -1,4 +1,4 @@
|
||||||
use crate::{ContextSelectionSet, GQLErrorWithPosition, GQLQueryError, Result};
|
use crate::{ContextSelectionSet, ErrorWithPosition, QueryError, Result};
|
||||||
use graphql_parser::query::Value;
|
use graphql_parser::query::Value;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -34,7 +34,7 @@ impl<T: GQLInputValue> GQLInputValue for Vec<T> {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: Self::type_name(),
|
expect: Self::type_name(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ impl<T: GQLOutputValue + Send> GQLOutputValue for Option<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait GQLObject: GQLType + GQLOutputValue {}
|
pub trait GQLObject: GQLOutputValue {}
|
||||||
|
|
||||||
pub struct GQLEmptyMutation;
|
pub struct GQLEmptyMutation;
|
||||||
|
|
||||||
|
@ -95,11 +95,11 @@ impl GQLType for GQLEmptyMutation {
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl GQLOutputValue for GQLEmptyMutation {
|
impl GQLOutputValue for GQLEmptyMutation {
|
||||||
async fn resolve(self, ctx: &ContextSelectionSet<'_>) -> Result<serde_json::Value> {
|
async fn resolve(self, ctx: &ContextSelectionSet<'_>) -> Result<serde_json::Value> {
|
||||||
anyhow::bail!(GQLQueryError::NotConfiguredMutations.with_position(ctx.item.span.0));
|
anyhow::bail!(QueryError::NotConfiguredMutations.with_position(ctx.item.span.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GQLObject for GQLEmptyMutation {}
|
impl GQLObject for GQLEmptyMutation {}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait GQLInputObject: GQLType + GQLInputValue {}
|
pub trait GQLInputObject: GQLInputValue {}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{GQLQueryError, GQLScalar, Result, Value};
|
use crate::{QueryError, Scalar, Result, Value};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
impl GQLScalar for Uuid {
|
impl Scalar for Uuid {
|
||||||
fn type_name() -> &'static str {
|
fn type_name() -> &'static str {
|
||||||
"UUID"
|
"UUID"
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ impl GQLScalar for Uuid {
|
||||||
match value {
|
match value {
|
||||||
Value::String(s) => Ok(Uuid::parse_str(&s)?),
|
Value::String(s) => Ok(Uuid::parse_str(&s)?),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(GQLQueryError::ExpectedType {
|
return Err(QueryError::ExpectedType {
|
||||||
expect: Self::type_name().to_string(),
|
expect: Self::type_name().to_string(),
|
||||||
actual: value,
|
actual: value,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user