From e890e9b4bded6844fea0343cbf162169684953fc Mon Sep 17 00:00:00 2001 From: rpiper Date: Sun, 14 May 2017 19:33:37 -0600 Subject: [PATCH] Removed from_json, leveraged the already implemented serialization trait and added a serialization implementation for the graphql result. --- src/integrations/serde.rs | 111 ++++++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 29 deletions(-) diff --git a/src/integrations/serde.rs b/src/integrations/serde.rs index 6d298787..c4e09269 100644 --- a/src/integrations/serde.rs +++ b/src/integrations/serde.rs @@ -3,41 +3,13 @@ use serde::ser::SerializeMap; use std::fmt; use std::collections::HashMap; -use ::{GraphQLError, Value}; +use ::{GraphQLError, Value, Variables}; use ast::InputValue; use executor::ExecutionError; use parser::{ParseError, Spanning, SourcePosition}; use validation::RuleError; -use serde_json::Value as Json; -impl InputValue { - /// Converts serde_json::Value to juniper::InputValue - pub fn from_json(json: Json) -> InputValue { - match json { - Json::Number(num) => { - if let Some(number) = num.as_i64() { - InputValue::int(number) - } - else if let Some(number) = num.as_f64() { - InputValue::float(number) - } - else if let Some(number) = num.as_u64() { - InputValue::float(number as f64) - } - else { - panic!("Invalid number data type was found."); - } - } - Json::String(s) => InputValue::string(s), - Json::Bool(b) => InputValue::boolean(b), - Json::Array(a) => InputValue::list(a.into_iter().map(InputValue::from_json).collect()), - Json::Object(o) => InputValue::object(o.into_iter().map(|(k, v)| (k, InputValue::from_json(v))).collect()), - Json::Null => InputValue::null(), - } - } -} - impl ser::Serialize for ExecutionError { fn serialize(&self, serializer: S) -> Result where S: ser::Serializer, @@ -242,3 +214,84 @@ impl ser::Serialize for Value { } } } + +/// The expected structure of the decoded JSON Document for either Post or Get requests. +#[cfg(feature="iron-handlers")] +#[derive(Deserialize)] +pub struct GraphQlQuery { + query: String, + #[serde(rename = "operationName")] + operation_name: Option, + variables: Option +} + +impl GraphQlQuery { + + pub fn new(query: String, + operation_name: Option, + variables: Option + ) -> GraphQlQuery { + GraphQlQuery { + query: query, + operation_name: operation_name, + variables: variables + } + } + + pub fn query(&self) -> &str { + self.query.as_str() + } + + pub fn operation_name(&self) -> Option<&str> { + self.operation_name.as_ref().map(|oper_name| &**oper_name) + } + + pub fn variables(&self) -> Variables { + self.variables.as_ref().and_then(|iv| { + iv.to_object_value().map(|o| { + o.into_iter().map(|(k, v)| (k.to_owned(), v.clone())).collect() + }) + }).unwrap_or_default() + } + +} + + +#[cfg(feature="iron-handlers")] +pub struct WrappedGraphQLResult<'a>(Result<(Value, Vec), GraphQLError<'a>>); + +impl<'a> WrappedGraphQLResult<'a> { + pub fn new(result: Result<(Value, Vec), + GraphQLError<'a>> + ) -> WrappedGraphQLResult<'a> { + WrappedGraphQLResult(result) + } +} + +impl<'a> ser::Serialize for WrappedGraphQLResult<'a> { + fn serialize(&self, serializer: S) -> Result + where S: ser::Serializer, + { + match self.0 { + Ok((ref res, ref err)) => { + let mut map = try!(serializer.serialize_map(None)); + + try!(map.serialize_key("data")); + try!(map.serialize_value(res)); + + if !err.is_empty() { + try!(map.serialize_key("errors")); + try!(map.serialize_value(err)); + } + + map.end() + }, + Err(ref err) => { + let mut map = try!(serializer.serialize_map(Some(1))); + try!(map.serialize_key("errors")); + try!(map.serialize_value(err)); + map.end() + }, + } + } +}