Merge pull request #12 from zaeleus/rustc_serialize

Make rustc-serialize optional
This commit is contained in:
Magnus Hallin 2017-01-15 11:46:45 +01:00 committed by GitHub
commit ba4c54f1a2
7 changed files with 193 additions and 115 deletions

View file

@ -15,13 +15,13 @@ harness = false
path = "benches/bench.rs"
[features]
default = []
default = ["rustc-serialize"]
nightly = []
iron-handlers = ["iron"]
iron-handlers = ["iron", "rustc-serialize"]
expose-test-schema = []
[dependencies]
rustc-serialize = "^0.3.19"
rustc-serialize = { version = "^0.3.19", optional = true }
iron = { version = "^0.4.0", optional = true }
serde = { version = "^0.8.21", optional = true }

View file

@ -4,8 +4,6 @@ use std::hash::Hash;
use std::vec;
use std::slice;
use rustc_serialize::json::{ToJson, Json};
use parser::Spanning;
/// A type literal in the syntax tree
@ -266,26 +264,6 @@ impl InputValue {
InputValue::Object(o)
}
/// Convert a `Json` structure into an `InputValue`.
///
/// This consumes the JSON instance.
///
/// Notes:
/// * No enums or variables will be produced by this method.
/// * All lists and objects will be unlocated
pub fn from_json(json: Json) -> InputValue {
match json {
Json::I64(i) => InputValue::int(i),
Json::U64(u) => InputValue::float(u as f64),
Json::F64(f) => InputValue::float(f),
Json::String(s) => InputValue::string(s),
Json::Boolean(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(),
}
}
/// Resolve all variables to their values.
pub fn into_const(self, vars: &HashMap<String, InputValue>) -> InputValue {
match self {
@ -403,17 +381,38 @@ impl InputValue {
}
}
impl ToJson for InputValue {
fn to_json(&self) -> Json {
impl fmt::Display for InputValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
InputValue::Null | InputValue::Variable(_) => Json::Null,
InputValue::Int(i) => Json::I64(i),
InputValue::Float(f) => Json::F64(f),
InputValue::String(ref s) | InputValue::Enum(ref s) => Json::String(s.clone()),
InputValue::Boolean(b) => Json::Boolean(b),
InputValue::List(ref l) => Json::Array(l.iter().map(|x| x.item.to_json()).collect()),
InputValue::Object(ref o) => Json::Object(o.iter().map(|&(ref k, ref v)| (k.item.clone(), v.item.to_json())).collect()),
}
InputValue::Null => write!(f, "null"),
InputValue::Int(v) => write!(f, "{}", v),
InputValue::Float(v) => write!(f, "{}", v),
InputValue::String(ref v) => write!(f, "\"{}\"", v),
InputValue::Boolean(v) => write!(f, "{}", v),
InputValue::Enum(ref v) => write!(f, "{}", v),
InputValue::Variable(ref v) => write!(f, "${}", v),
InputValue::List(ref v) => {
try!(write!(f, "["));
for (i, spanning) in v.iter().enumerate() {
try!(spanning.item.fmt(f));
if i < v.len() - 1 { try!(write!(f, ", ")); }
}
write!(f, "]")
},
InputValue::Object(ref o) => {
try!(write!(f, "{{"));
for (i, &(ref k, ref v)) in o.iter().enumerate() {
try!(write!(f, "{}: ", k.item));
try!(v.item.fmt(f));
if i < o.len() - 1 { try!(write!(f, ", ")); }
}
write!(f, "}}")
}
}
}
}
@ -448,3 +447,44 @@ impl<'a> VariableDefinitions<'a> {
self.items.iter()
}
}
#[cfg(test)]
mod tests {
use super::InputValue;
use parser::Spanning;
#[test]
fn test_input_value_fmt() {
let value = InputValue::null();
assert_eq!(format!("{}", value), "null");
let value = InputValue::int(123);
assert_eq!(format!("{}", value), "123");
let value = InputValue::float(12.3);
assert_eq!(format!("{}", value), "12.3");
let value = InputValue::string("FOO".to_owned());
assert_eq!(format!("{}", value), "\"FOO\"");
let value = InputValue::boolean(true);
assert_eq!(format!("{}", value), "true");
let value = InputValue::enum_value("BAR".to_owned());
assert_eq!(format!("{}", value), "BAR");
let value = InputValue::variable("baz".to_owned());
assert_eq!(format!("{}", value), "$baz");
let list = vec![InputValue::int(1), InputValue::int(2)];
let value = InputValue::list(list);
assert_eq!(format!("{}", value), "[1, 2]");
let object = vec![
(Spanning::unlocated("foo".to_owned()), Spanning::unlocated(InputValue::int(1))),
(Spanning::unlocated("bar".to_owned()), Spanning::unlocated(InputValue::int(2))),
];
let value = InputValue::parsed_object(object);
assert_eq!(format!("{}", value), "{foo: 1, bar: 2}");
}
}

View file

@ -1,2 +1,3 @@
#[cfg(feature="iron-handlers")] pub mod iron_handlers;
#[cfg(feature="rustc-serialize")] pub mod rustc_serialize;
#[cfg(feature="serde")] pub mod serde;

View file

@ -0,0 +1,114 @@
use rustc_serialize::json::{ToJson, Json};
use ::{GraphQLError, Value};
use ast::InputValue;
use executor::ExecutionError;
use parser::{ParseError, Spanning, SourcePosition};
use validation::RuleError;
fn parse_error_to_json(err: &Spanning<ParseError>) -> Json {
Json::Array(vec![
Json::Object(vec![
("message".to_owned(), format!("{}", err.item).to_json()),
("locations".to_owned(), vec![
Json::Object(vec![
("line".to_owned(), (err.start.line() + 1).to_json()),
("column".to_owned(), (err.start.column() + 1).to_json())
].into_iter().collect()),
].to_json()),
].into_iter().collect()),
])
}
impl ToJson for ExecutionError {
fn to_json(&self) -> Json {
Json::Object(vec![
("message".to_owned(), self.message().to_json()),
("locations".to_owned(), vec![self.location().clone()].to_json()),
("path".to_owned(), self.path().to_json()),
].into_iter().collect())
}
}
impl<'a> ToJson for GraphQLError<'a> {
fn to_json(&self) -> Json {
match *self {
GraphQLError::ParseError(ref err) => parse_error_to_json(err),
GraphQLError::ValidationError(ref errs) => errs.to_json(),
GraphQLError::MultipleOperationsProvided => Json::String(
"Must provide operation name if query contains multiple operations".to_owned()),
GraphQLError::NoOperationProvided => Json::String(
"Must provide an operation".to_owned()),
GraphQLError::UnknownOperationName => Json::String(
"Unknown operation".to_owned()),
}
}
}
impl ToJson for InputValue {
fn to_json(&self) -> Json {
match *self {
InputValue::Null | InputValue::Variable(_) => Json::Null,
InputValue::Int(i) => Json::I64(i),
InputValue::Float(f) => Json::F64(f),
InputValue::String(ref s) | InputValue::Enum(ref s) => Json::String(s.clone()),
InputValue::Boolean(b) => Json::Boolean(b),
InputValue::List(ref l) => Json::Array(l.iter().map(|x| x.item.to_json()).collect()),
InputValue::Object(ref o) => Json::Object(o.iter().map(|&(ref k, ref v)| (k.item.clone(), v.item.to_json())).collect()),
}
}
}
impl InputValue {
/// Convert a `Json` structure into an `InputValue`.
///
/// This consumes the JSON instance.
///
/// Notes:
/// * No enums or variables will be produced by this method.
/// * All lists and objects will be unlocated
pub fn from_json(json: Json) -> InputValue {
match json {
Json::I64(i) => InputValue::int(i),
Json::U64(u) => InputValue::float(u as f64),
Json::F64(f) => InputValue::float(f),
Json::String(s) => InputValue::string(s),
Json::Boolean(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 ToJson for RuleError {
fn to_json(&self) -> Json {
Json::Object(vec![
("message".to_owned(), self.message().to_json()),
("locations".to_owned(), self.locations().to_json()),
].into_iter().collect())
}
}
impl ToJson for SourcePosition {
fn to_json(&self) -> Json {
Json::Object(vec![
("line".to_owned(), (self.line() + 1).to_json()),
("column".to_owned(), (self.column() + 1).to_json()),
].into_iter().collect())
}
}
impl ToJson for Value {
fn to_json(&self) -> Json {
match *self {
Value::Null => Json::Null,
Value::Int(i) => Json::I64(i),
Value::Float(f) => Json::F64(f),
Value::String(ref s) => Json::String(s.clone()),
Value::Boolean(b) => Json::Boolean(b),
Value::List(ref l) => Json::Array(l.iter().map(|x| x.to_json()).collect()),
Value::Object(ref o) => Json::Object(o.iter().map(|(k,v)| (k.clone(), v.to_json())).collect()),
}
}
}

View file

@ -186,7 +186,7 @@ built-in [GraphiQL][6] handler included.
#![cfg_attr(feature="nightly", feature(test))]
#![warn(missing_docs)]
extern crate rustc_serialize;
#[cfg(feature="rustc-serialize")] extern crate rustc_serialize;
#[cfg(feature="serde")] extern crate serde;
#[cfg(feature="nightly")] extern crate test;
@ -211,9 +211,7 @@ mod integrations;
use std::collections::HashMap;
use rustc_serialize::json::{ToJson, Json};
use parser::{parse_document_source, ParseError, Spanning, SourcePosition};
use parser::{parse_document_source, ParseError, Spanning};
use validation::{ValidatorContext, visit_all_rules, validate_input_values};
use executor::execute_validated_query;
@ -285,63 +283,6 @@ impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
}
}
impl<'a> ToJson for GraphQLError<'a> {
fn to_json(&self) -> Json {
match *self {
GraphQLError::ParseError(ref err) => parse_error_to_json(err),
GraphQLError::ValidationError(ref errs) => errs.to_json(),
GraphQLError::MultipleOperationsProvided => Json::String(
"Must provide operation name if query contains multiple operations".to_owned()),
GraphQLError::NoOperationProvided => Json::String(
"Must provide an operation".to_owned()),
GraphQLError::UnknownOperationName => Json::String(
"Unknown operation".to_owned()),
}
}
}
fn parse_error_to_json(err: &Spanning<ParseError>) -> Json {
Json::Array(vec![
Json::Object(vec![
("message".to_owned(), format!("{}", err.item).to_json()),
("locations".to_owned(), vec![
Json::Object(vec![
("line".to_owned(), (err.start.line() + 1).to_json()),
("column".to_owned(), (err.start.column() + 1).to_json())
].into_iter().collect()),
].to_json()),
].into_iter().collect()),
])
}
impl ToJson for RuleError {
fn to_json(&self) -> Json {
Json::Object(vec![
("message".to_owned(), self.message().to_json()),
("locations".to_owned(), self.locations().to_json()),
].into_iter().collect())
}
}
impl ToJson for SourcePosition {
fn to_json(&self) -> Json {
Json::Object(vec![
("line".to_owned(), (self.line() + 1).to_json()),
("column".to_owned(), (self.column() + 1).to_json()),
].into_iter().collect())
}
}
impl ToJson for ExecutionError {
fn to_json(&self) -> Json {
Json::Object(vec![
("message".to_owned(), self.message().to_json()),
("locations".to_owned(), vec![self.location().clone()].to_json()),
("path".to_owned(), self.path().to_json()),
].into_iter().collect())
}
}
#[doc(hidden)]
pub fn to_camel_case(s: &str) -> String {
let mut dest = String::new();

View file

@ -1,5 +1,3 @@
use rustc_serialize::json::ToJson;
use types::base::{GraphQLType, Arguments, TypeKind};
use executor::{Executor, Registry, ExecutionResult};
@ -191,7 +189,7 @@ graphql_object!(<'a> Argument<'a>: SchemaType<'a> as "__InputValue" |&self| {
}
field default_value() -> Option<String> {
self.default_value.as_ref().map(|v| v.to_json().to_string())
self.default_value.as_ref().map(|v| format!("{}", v))
}
});

View file

@ -1,8 +1,6 @@
use std::collections::HashMap;
use std::hash::Hash;
use rustc_serialize::json::{ToJson, Json};
use parser::Spanning;
use ast::{InputValue, ToInputValue};
@ -100,20 +98,6 @@ impl Value {
}
}
impl ToJson for Value {
fn to_json(&self) -> Json {
match *self {
Value::Null => Json::Null,
Value::Int(i) => Json::I64(i),
Value::Float(f) => Json::F64(f),
Value::String(ref s) => Json::String(s.clone()),
Value::Boolean(b) => Json::Boolean(b),
Value::List(ref l) => Json::Array(l.iter().map(|x| x.to_json()).collect()),
Value::Object(ref o) => Json::Object(o.iter().map(|(k,v)| (k.clone(), v.to_json())).collect()),
}
}
}
impl ToInputValue for Value {
fn to(&self) -> InputValue {
match *self {