Support default values
This commit is contained in:
parent
d8c7494dec
commit
602f6a656f
|
@ -53,23 +53,24 @@
|
|||
- [X] Non-Null
|
||||
- [ ] Object
|
||||
- [ ] Generic Types
|
||||
- [X] Lifetime cycle
|
||||
- [X] Lifetime cycle
|
||||
- [X] Enum
|
||||
- [X] InputObject
|
||||
- [ ] Field default value
|
||||
- [X] Field default value
|
||||
- [X] Deprecated flag
|
||||
- [ ] Interface
|
||||
- [ ] Union
|
||||
- [ ] Query
|
||||
- [X] Fields
|
||||
- [X] Arguments
|
||||
- [ ] Default value
|
||||
- [X] Default value
|
||||
- [X] Deprecated flag
|
||||
- [X] Alias
|
||||
- [ ] Fragments
|
||||
- [ ] Inline fragments
|
||||
- [X] Operation name
|
||||
- [X] Variables
|
||||
- [X] Default value
|
||||
- [X] Parse value
|
||||
- [ ] Check type
|
||||
- [ ] Directives
|
||||
|
|
|
@ -176,6 +176,12 @@ impl Field {
|
|||
} else if nv.path.is_ident("default") {
|
||||
if let syn::Lit::Str(lit) = &nv.lit {
|
||||
match parse_value(&lit.value()) {
|
||||
Ok(Value::Variable(_)) => {
|
||||
return Err(Error::new_spanned(
|
||||
&nv.lit,
|
||||
"The default cannot be a variable",
|
||||
))
|
||||
}
|
||||
Ok(value) => default = Some(value),
|
||||
Err(err) => {
|
||||
return Err(Error::new_spanned(
|
||||
|
@ -406,6 +412,12 @@ impl InputField {
|
|||
} else if nv.path.is_ident("default") {
|
||||
if let syn::Lit::Str(lit) = nv.lit {
|
||||
match parse_value(&lit.value()) {
|
||||
Ok(Value::Variable(_)) => {
|
||||
return Err(Error::new_spanned(
|
||||
&lit,
|
||||
"The default cannot be a variable",
|
||||
))
|
||||
}
|
||||
Ok(value) => default = Some(value),
|
||||
Err(err) => {
|
||||
return Err(Error::new_spanned(
|
||||
|
|
|
@ -98,11 +98,11 @@ pub fn generate(enum_args: &args::Enum, input: &DeriveInput) -> Result<TokenStre
|
|||
}
|
||||
|
||||
impl #crate_name::GQLInputValue for #ident {
|
||||
fn parse(value: #crate_name::Value) -> Option<Self> {
|
||||
fn parse(value: &#crate_name::Value) -> Option<Self> {
|
||||
#crate_name::GQLEnum::parse_enum(value)
|
||||
}
|
||||
|
||||
fn parse_from_json(value: #crate_name::serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &#crate_name::serde_json::Value) -> Option<Self> {
|
||||
#crate_name::GQLEnum::parse_json_enum(value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::args;
|
||||
use crate::utils::get_crate_name;
|
||||
use crate::utils::{build_value_repr, get_crate_name};
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{Data, DeriveInput, Error, Result};
|
||||
|
@ -63,12 +63,45 @@ pub fn generate(object_args: &args::InputObject, input: &DeriveInput) -> Result<
|
|||
quote! {Some(#s)}
|
||||
})
|
||||
.unwrap_or_else(|| quote! {None});
|
||||
get_fields.push(quote! {
|
||||
let #ident:#ty = #crate_name::GQLInputValue::parse(obj.remove(#name).unwrap_or(#crate_name::Value::Null))?;
|
||||
});
|
||||
get_json_fields.push(quote! {
|
||||
let #ident:#ty = #crate_name::GQLInputValue::parse_from_json(obj.remove(#name).unwrap_or(#crate_name::serde_json::Value::Null))?;
|
||||
});
|
||||
|
||||
if let Some(default) = &field_args.default {
|
||||
let default_repr = build_value_repr(&crate_name, default);
|
||||
get_fields.push(quote! {
|
||||
let #ident:#ty = {
|
||||
match obj.get(#name) {
|
||||
Some(value) => #crate_name::GQLInputValue::parse(value)?,
|
||||
None => {
|
||||
let default = #default_repr;
|
||||
#crate_name::GQLInputValue::parse(&value)?
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
} else {
|
||||
get_fields.push(quote! {
|
||||
let #ident:#ty = #crate_name::GQLInputValue::parse(obj.get(#name).unwrap_or(&#crate_name::Value::Null))?;
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(default) = &field_args.default {
|
||||
let default_repr = build_value_repr(&crate_name, default);
|
||||
get_json_fields.push(quote! {
|
||||
let #ident:#ty = match obj.get(#name) {
|
||||
None => {
|
||||
let default_value = #default_repr;
|
||||
#crate_name::GQLInputValue::parse(&default_value)?
|
||||
}
|
||||
Some(value) => {
|
||||
#crate_name::GQLInputValue::parse_from_json(&value)?
|
||||
}
|
||||
};
|
||||
});
|
||||
} else {
|
||||
get_json_fields.push(quote! {
|
||||
let #ident:#ty = #crate_name::GQLInputValue::parse_from_json(&obj.get(#name).unwrap_or(&#crate_name::serde_json::Value::Null))?;
|
||||
});
|
||||
}
|
||||
|
||||
fields.push(ident);
|
||||
schema_fields.push(quote! {
|
||||
#crate_name::registry::InputValue {
|
||||
|
@ -98,10 +131,10 @@ pub fn generate(object_args: &args::InputObject, input: &DeriveInput) -> Result<
|
|||
}
|
||||
|
||||
impl #crate_name::GQLInputValue for #ident {
|
||||
fn parse(value: #crate_name::Value) -> Option<Self> {
|
||||
fn parse(value: &#crate_name::Value) -> Option<Self> {
|
||||
use #crate_name::GQLType;
|
||||
|
||||
if let #crate_name::Value::Object(mut obj) = value {
|
||||
if let #crate_name::Value::Object(obj) = value {
|
||||
#(#get_fields)*
|
||||
Some(Self { #(#fields),* })
|
||||
} else {
|
||||
|
@ -109,9 +142,9 @@ pub fn generate(object_args: &args::InputObject, input: &DeriveInput) -> Result<
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: #crate_name::serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &#crate_name::serde_json::Value) -> Option<Self> {
|
||||
use #crate_name::GQLType;
|
||||
if let #crate_name::serde_json::Value::Object(mut obj) = value {
|
||||
if let #crate_name::serde_json::Value::Object(obj) = value {
|
||||
#(#get_json_fields)*
|
||||
Some(Self { #(#fields),* })
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::args;
|
||||
use crate::utils::get_crate_name;
|
||||
use crate::utils::{build_value_repr, get_crate_name};
|
||||
use inflector::Inflector;
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
|
@ -59,7 +59,7 @@ pub fn generate(object_args: &args::Object, input: &DeriveInput) -> Result<Token
|
|||
.as_ref()
|
||||
.map(|s| quote! { Some(#s) })
|
||||
.unwrap_or_else(|| quote! {None});
|
||||
let default = arg
|
||||
let schema_default = arg
|
||||
.default
|
||||
.as_ref()
|
||||
.map(|v| {
|
||||
|
@ -69,16 +69,26 @@ pub fn generate(object_args: &args::Object, input: &DeriveInput) -> Result<Token
|
|||
.unwrap_or_else(|| quote! {None});
|
||||
|
||||
decl_params.push(quote! { #snake_case_name: #ty });
|
||||
|
||||
let default = match &arg.default {
|
||||
Some(default) => {
|
||||
let repr = build_value_repr(&crate_name, &default);
|
||||
quote! {Some(|| #repr)}
|
||||
}
|
||||
None => quote! { None },
|
||||
};
|
||||
get_params.push(quote! {
|
||||
let #snake_case_name: #ty = ctx_field.param_value(#name_str)?;
|
||||
let #snake_case_name: #ty = ctx_field.param_value(#name_str, #default)?;
|
||||
});
|
||||
|
||||
use_params.push(quote! { #snake_case_name });
|
||||
|
||||
schema_args.push(quote! {
|
||||
#crate_name::registry::InputValue {
|
||||
name: #name_str,
|
||||
description: #desc,
|
||||
ty: <#ty as #crate_name::GQLType>::create_type_info(registry),
|
||||
default_value: #default,
|
||||
default_value: #schema_default,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use graphql_parser::parse_query;
|
||||
use graphql_parser::query::{Definition, OperationDefinition, ParseError, Query, Value};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::Ident;
|
||||
|
@ -12,18 +14,13 @@ pub fn get_crate_name(internal: bool) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_value(
|
||||
s: &str,
|
||||
) -> Result<graphql_parser::query::Value, graphql_parser::query::ParseError> {
|
||||
let mut doc =
|
||||
graphql_parser::query::parse_query(&format!("query ($a:Int!={}) {{ dummy }}", s))?;
|
||||
pub fn parse_value(s: &str) -> Result<Value, ParseError> {
|
||||
let mut doc = parse_query(&format!("query ($a:Int!={}) {{ dummy }}", s))?;
|
||||
let definition = doc.definitions.remove(0);
|
||||
if let graphql_parser::query::Definition::Operation(
|
||||
graphql_parser::query::OperationDefinition::Query(graphql_parser::query::Query {
|
||||
mut variable_definitions,
|
||||
..
|
||||
}),
|
||||
) = definition
|
||||
if let Definition::Operation(OperationDefinition::Query(Query {
|
||||
mut variable_definitions,
|
||||
..
|
||||
})) = definition
|
||||
{
|
||||
let var = variable_definitions.remove(0);
|
||||
Ok(var.default_value.unwrap())
|
||||
|
@ -31,3 +28,53 @@ pub fn parse_value(
|
|||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_value_repr(crate_name: &TokenStream, value: &Value) -> TokenStream {
|
||||
match value {
|
||||
Value::Variable(_) => unreachable!(),
|
||||
Value::Int(n) => {
|
||||
let n = n.as_i64().unwrap();
|
||||
quote! { #crate_name::Value::Int((#n as i32).into()) }
|
||||
}
|
||||
Value::Float(n) => {
|
||||
quote! { #crate_name::Value::Float(#n) }
|
||||
}
|
||||
Value::String(s) => {
|
||||
quote! { #crate_name::Value::String(#s.to_string()) }
|
||||
}
|
||||
Value::Boolean(n) => {
|
||||
quote! { #crate_name::Value::Boolean(#n) }
|
||||
}
|
||||
Value::Null => {
|
||||
quote! { #crate_name::Value::Null }
|
||||
}
|
||||
Value::Enum(n) => {
|
||||
quote! { #crate_name::Value::Enum(#n.to_string()) }
|
||||
}
|
||||
Value::List(ls) => {
|
||||
let members = ls
|
||||
.iter()
|
||||
.map(|v| build_value_repr(crate_name, v))
|
||||
.collect::<Vec<_>>();
|
||||
quote! { #crate_name::Value::List(vec![#(#members),*]) }
|
||||
}
|
||||
Value::Object(obj) => {
|
||||
let members = obj
|
||||
.iter()
|
||||
.map(|(n, v)| {
|
||||
let value = build_value_repr(crate_name, v);
|
||||
quote! {
|
||||
obj.insert(#n.to_string(), #value);
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
quote! {
|
||||
{
|
||||
let mut obj = std::collections::BTreeMap::new();
|
||||
#(#members)*
|
||||
obj
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,15 @@ struct MyInputObj {
|
|||
a: i32,
|
||||
b: i32,
|
||||
}
|
||||
|
||||
#[async_graphql::Object(
|
||||
field(name = "a", type = "i32"),
|
||||
field(owned, name = "b", type = "i32"),
|
||||
field(
|
||||
owned,
|
||||
name = "b",
|
||||
type = "i32",
|
||||
arg(name = "v", type = "i32", default = "123")
|
||||
),
|
||||
field(owned, name = "c", type = "Option<String>")
|
||||
)]
|
||||
struct MyObj {
|
||||
|
@ -25,8 +31,8 @@ impl MyObjFields for MyObj {
|
|||
Ok(&self.value)
|
||||
}
|
||||
|
||||
async fn b(&self, ctx: &async_graphql::Context<'_>) -> async_graphql::Result<i32> {
|
||||
Ok(999)
|
||||
async fn b(&self, ctx: &async_graphql::Context<'_>, v: i32) -> async_graphql::Result<i32> {
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
async fn c(&self, ctx: &async_graphql::Context<'_>) -> async_graphql::Result<Option<String>> {
|
||||
|
@ -37,14 +43,16 @@ impl MyObjFields for MyObj {
|
|||
#[async_std::main]
|
||||
async fn main() {
|
||||
let schema = async_graphql::Schema::<MyObj, async_graphql::GQLEmptyMutation>::new();
|
||||
let res = schema
|
||||
.query(
|
||||
MyObj { value: 100 },
|
||||
async_graphql::GQLEmptyMutation,
|
||||
"{ a b c __schema { types { kind name description } } }",
|
||||
)
|
||||
.execute()
|
||||
.await
|
||||
.unwrap();
|
||||
serde_json::to_writer_pretty(std::io::stdout(), &res).unwrap();
|
||||
for _ in 0..1000 {
|
||||
let res = schema
|
||||
.query(
|
||||
MyObj { value: 100 },
|
||||
async_graphql::GQLEmptyMutation,
|
||||
"{ a b c __schema { types { kind name description fields(includeDeprecated: false) { name args { name defaultValue } } } } }",
|
||||
)
|
||||
.execute()
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
// serde_json::to_writer_pretty(std::io::stdout(), &res).unwrap();
|
||||
}
|
||||
|
|
12
src/base.rs
12
src/base.rs
|
@ -15,8 +15,8 @@ pub trait GQLType {
|
|||
|
||||
#[doc(hidden)]
|
||||
pub trait GQLInputValue: GQLType + Sized {
|
||||
fn parse(value: Value) -> Option<Self>;
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self>;
|
||||
fn parse(value: &Value) -> Option<Self>;
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self>;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -36,8 +36,8 @@ pub trait Scalar: Sized + Send {
|
|||
fn description() -> Option<&'static str> {
|
||||
None
|
||||
}
|
||||
fn parse(value: Value) -> Option<Self>;
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self>;
|
||||
fn parse(value: &Value) -> Option<Self>;
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self>;
|
||||
fn to_json(&self) -> Result<serde_json::Value>;
|
||||
}
|
||||
|
||||
|
@ -55,11 +55,11 @@ impl<T: Scalar> GQLType for T {
|
|||
}
|
||||
|
||||
impl<T: Scalar> GQLInputValue for T {
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
T::parse(value)
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
T::parse_from_json(value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,11 @@ impl<'a, T> ContextBase<'a, T> {
|
|||
|
||||
impl<'a> ContextBase<'a, &'a Field> {
|
||||
#[doc(hidden)]
|
||||
pub fn param_value<T: GQLInputValue>(&self, name: &str) -> Result<T> {
|
||||
pub fn param_value<T: GQLInputValue, F: FnOnce() -> Value>(
|
||||
&self,
|
||||
name: &str,
|
||||
default: Option<F>,
|
||||
) -> Result<T> {
|
||||
let value = self
|
||||
.arguments
|
||||
.iter()
|
||||
|
@ -88,26 +92,42 @@ impl<'a> ContextBase<'a, &'a Field> {
|
|||
if let Some(Value::Variable(var_name)) = &value {
|
||||
if let Some(vars) = &self.variables {
|
||||
if let Some(var_value) = vars.get(&*var_name).cloned() {
|
||||
let res =
|
||||
GQLInputValue::parse_from_json(var_value.clone()).ok_or_else(|| {
|
||||
QueryError::ExpectedJsonType {
|
||||
expect: T::qualified_type_name(),
|
||||
actual: var_value,
|
||||
}
|
||||
.with_position(self.item.position)
|
||||
})?;
|
||||
let res = GQLInputValue::parse_from_json(&var_value).ok_or_else(|| {
|
||||
QueryError::ExpectedJsonType {
|
||||
expect: T::qualified_type_name(),
|
||||
actual: var_value,
|
||||
}
|
||||
.with_position(self.item.position)
|
||||
})?;
|
||||
return Ok(res);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(default) = default {
|
||||
let value = default();
|
||||
let res = GQLInputValue::parse(&value).ok_or_else(|| {
|
||||
QueryError::ExpectedType {
|
||||
expect: T::qualified_type_name(),
|
||||
actual: value,
|
||||
}
|
||||
.with_position(self.item.position)
|
||||
})?;
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
return Err(QueryError::VarNotDefined {
|
||||
var_name: var_name.clone(),
|
||||
}
|
||||
.into());
|
||||
};
|
||||
|
||||
let value = value.unwrap_or(Value::Null);
|
||||
let res = GQLInputValue::parse(value.clone()).ok_or_else(|| {
|
||||
let value = if let (Some(default), None) = (default, &value) {
|
||||
default()
|
||||
} else {
|
||||
value.unwrap_or(Value::Null)
|
||||
};
|
||||
|
||||
let res = GQLInputValue::parse(&value).ok_or_else(|| {
|
||||
QueryError::ExpectedType {
|
||||
expect: T::qualified_type_name(),
|
||||
actual: value,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::model::__Type;
|
||||
use crate::model::{__InputValue, __Type};
|
||||
use crate::{registry, Context, Result};
|
||||
use async_graphql_derive::Object;
|
||||
|
||||
|
@ -7,6 +7,7 @@ use async_graphql_derive::Object;
|
|||
desc = "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.",
|
||||
field(name = "name", type = "String", owned),
|
||||
field(name = "description", type = "Option<String>", owned),
|
||||
field(name = "args", type = "Vec<__InputValue>", owned),
|
||||
field(name = "type", resolver = "ty", type = "__Type", owned),
|
||||
field(name = "isDeprecated", type = "bool", owned),
|
||||
field(name = "deprecationReason", type = "Option<String>", owned)
|
||||
|
@ -27,6 +28,18 @@ impl<'a> __FieldFields for __Field<'a> {
|
|||
Ok(self.field.description.map(|s| s.to_string()))
|
||||
}
|
||||
|
||||
async fn args<'b>(&'b self, _: &Context<'_>) -> Result<Vec<__InputValue<'b>>> {
|
||||
Ok(self
|
||||
.field
|
||||
.args
|
||||
.iter()
|
||||
.map(|input_value| __InputValue {
|
||||
registry: self.registry,
|
||||
input_value,
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
async fn ty<'b>(&'b self, _: &Context<'_>) -> Result<__Type<'b>> {
|
||||
Ok(__Type {
|
||||
registry: self.registry,
|
||||
|
|
|
@ -17,7 +17,7 @@ Depending on the kind of a type, certain fields describe information about that
|
|||
name = "fields",
|
||||
type = "Option<Vec<__Field>>",
|
||||
owned,
|
||||
arg(name = "includeDeprecated", type = "bool")
|
||||
arg(name = "includeDeprecated", type = "bool", default="false")
|
||||
),
|
||||
field(name = "interfaces", type = "Option<Vec<__Type>>", owned),
|
||||
field(name = "possibleTypes", type = "Option<Vec<__Type>>", owned),
|
||||
|
@ -25,7 +25,7 @@ Depending on the kind of a type, certain fields describe information about that
|
|||
name = "enumValues",
|
||||
type = "Option<Vec<__EnumValue>>",
|
||||
owned,
|
||||
arg(name = "includeDeprecated", type = "bool")
|
||||
arg(name = "includeDeprecated", type = "bool", default="false")
|
||||
),
|
||||
field(name = "inputFields", type = "Option<Vec<__InputValue>>", owned),
|
||||
field(name = "ofType", type = "Option<__Type>", owned)
|
||||
|
|
|
@ -9,16 +9,16 @@ impl Scalar for bool {
|
|||
Some("The `Boolean` scalar type represents `true` or `false`.")
|
||||
}
|
||||
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::Boolean(n) => Some(n),
|
||||
Value::Boolean(n) => Some(*n),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::Bool(n) => Some(n),
|
||||
serde_json::Value::Bool(n) => Some(*n),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ impl Scalar for DateTime<Utc> {
|
|||
"DateTime"
|
||||
}
|
||||
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::String(s) => Some(Utc.datetime_from_str(&s, "%+").ok()?),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::String(s) => Some(Utc.datetime_from_str(&s, "%+").ok()?),
|
||||
_ => None,
|
||||
|
|
|
@ -12,15 +12,15 @@ macro_rules! impl_float_scalars {
|
|||
Some("The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).")
|
||||
}
|
||||
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::Int(n) => Some(n.as_i64().unwrap() as Self),
|
||||
Value::Float(n) => Some(n as Self),
|
||||
Value::Float(n) => Some(*n as Self),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::Number(n) => Some(n.as_f64().unwrap() as Self),
|
||||
_ => None
|
||||
|
|
|
@ -23,18 +23,18 @@ impl Scalar for ID {
|
|||
"ID"
|
||||
}
|
||||
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::Int(n) => Some(ID(n.as_i64().unwrap().to_string())),
|
||||
Value::String(s) => Some(ID(s)),
|
||||
Value::String(s) => Some(ID(s.clone())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::Number(n) if n.is_i64() => Some(ID(n.as_i64().unwrap().to_string())),
|
||||
serde_json::Value::String(s) => Some(ID(s)),
|
||||
serde_json::Value::String(s) => Some(ID(s.clone())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@ macro_rules! impl_integer_scalars {
|
|||
Some("The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.")
|
||||
}
|
||||
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::Int(n) => Some(n.as_i64().unwrap() as Self),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::Number(n) if n.is_i64() => Some(n.as_i64().unwrap() as Self),
|
||||
serde_json::Value::Number(n) => Some(n.as_f64().unwrap() as Self),
|
||||
|
|
|
@ -13,16 +13,16 @@ impl Scalar for String {
|
|||
Some(STRING_DESC)
|
||||
}
|
||||
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::String(s) => Some(s),
|
||||
Value::String(s) => Some(s.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::String(s) => Some(s),
|
||||
serde_json::Value::String(s) => Some(s.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ impl Scalar for Uuid {
|
|||
"UUID"
|
||||
}
|
||||
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::String(s) => Some(Uuid::parse_str(&s).ok()?),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::String(s) => Some(Uuid::parse_str(&s).ok()?),
|
||||
_ => None,
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct GQLEnumItem<T> {
|
|||
pub trait GQLEnum: GQLType + Sized + Eq + Send + Copy + Sized + 'static {
|
||||
fn items() -> &'static [GQLEnumItem<Self>];
|
||||
|
||||
fn parse_enum(value: Value) -> Option<Self> {
|
||||
fn parse_enum(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::Enum(s) => {
|
||||
let items = Self::items();
|
||||
|
@ -27,7 +27,7 @@ pub trait GQLEnum: GQLType + Sized + Eq + Send + Copy + Sized + 'static {
|
|||
None
|
||||
}
|
||||
|
||||
fn parse_json_enum(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_json_enum(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::String(s) => {
|
||||
let items = Self::items();
|
||||
|
|
|
@ -12,7 +12,7 @@ impl<T: GQLType> GQLType for Vec<T> {
|
|||
}
|
||||
|
||||
impl<T: GQLInputValue> GQLInputValue for Vec<T> {
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::List(values) => {
|
||||
let mut result = Vec::new();
|
||||
|
@ -25,7 +25,7 @@ impl<T: GQLInputValue> GQLInputValue for Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::Array(values) => {
|
||||
let mut result = Vec::new();
|
||||
|
|
|
@ -16,14 +16,14 @@ impl<T: GQLType> GQLType for Option<T> {
|
|||
}
|
||||
|
||||
impl<T: GQLInputValue> GQLInputValue for Option<T> {
|
||||
fn parse(value: Value) -> Option<Self> {
|
||||
fn parse(value: &Value) -> Option<Self> {
|
||||
match value {
|
||||
Value::Null => Some(None),
|
||||
_ => Some(GQLInputValue::parse(value)?),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_from_json(value: serde_json::Value) -> Option<Self> {
|
||||
fn parse_from_json(value: &serde_json::Value) -> Option<Self> {
|
||||
match value {
|
||||
serde_json::Value::Null => Some(None),
|
||||
_ => Some(GQLInputValue::parse_from_json(value)?),
|
||||
|
|
Loading…
Reference in New Issue