Skip to content

Commit ba4c54f

Browse files
authored
Merge pull request #12 from zaeleus/rustc_serialize
Make rustc-serialize optional
2 parents 8620eb1 + b78aef7 commit ba4c54f

File tree

7 files changed

+193
-115
lines changed

7 files changed

+193
-115
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ harness = false
1515
path = "benches/bench.rs"
1616

1717
[features]
18-
default = []
18+
default = ["rustc-serialize"]
1919
nightly = []
20-
iron-handlers = ["iron"]
20+
iron-handlers = ["iron", "rustc-serialize"]
2121
expose-test-schema = []
2222

2323
[dependencies]
24-
rustc-serialize = "^0.3.19"
24+
rustc-serialize = { version = "^0.3.19", optional = true }
2525
iron = { version = "^0.4.0", optional = true }
2626
serde = { version = "^0.8.21", optional = true }
2727

src/ast.rs

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use std::hash::Hash;
44
use std::vec;
55
use std::slice;
66

7-
use rustc_serialize::json::{ToJson, Json};
8-
97
use parser::Spanning;
108

119
/// A type literal in the syntax tree
@@ -266,26 +264,6 @@ impl InputValue {
266264
InputValue::Object(o)
267265
}
268266

269-
/// Convert a `Json` structure into an `InputValue`.
270-
///
271-
/// This consumes the JSON instance.
272-
///
273-
/// Notes:
274-
/// * No enums or variables will be produced by this method.
275-
/// * All lists and objects will be unlocated
276-
pub fn from_json(json: Json) -> InputValue {
277-
match json {
278-
Json::I64(i) => InputValue::int(i),
279-
Json::U64(u) => InputValue::float(u as f64),
280-
Json::F64(f) => InputValue::float(f),
281-
Json::String(s) => InputValue::string(s),
282-
Json::Boolean(b) => InputValue::boolean(b),
283-
Json::Array(a) => InputValue::list(a.into_iter().map(InputValue::from_json).collect()),
284-
Json::Object(o) => InputValue::object(o.into_iter().map(|(k,v)| (k, InputValue::from_json(v))).collect()),
285-
Json::Null => InputValue::null(),
286-
}
287-
}
288-
289267
/// Resolve all variables to their values.
290268
pub fn into_const(self, vars: &HashMap<String, InputValue>) -> InputValue {
291269
match self {
@@ -403,17 +381,38 @@ impl InputValue {
403381
}
404382
}
405383

406-
impl ToJson for InputValue {
407-
fn to_json(&self) -> Json {
384+
impl fmt::Display for InputValue {
385+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
408386
match *self {
409-
InputValue::Null | InputValue::Variable(_) => Json::Null,
410-
InputValue::Int(i) => Json::I64(i),
411-
InputValue::Float(f) => Json::F64(f),
412-
InputValue::String(ref s) | InputValue::Enum(ref s) => Json::String(s.clone()),
413-
InputValue::Boolean(b) => Json::Boolean(b),
414-
InputValue::List(ref l) => Json::Array(l.iter().map(|x| x.item.to_json()).collect()),
415-
InputValue::Object(ref o) => Json::Object(o.iter().map(|&(ref k, ref v)| (k.item.clone(), v.item.to_json())).collect()),
416-
}
387+
InputValue::Null => write!(f, "null"),
388+
InputValue::Int(v) => write!(f, "{}", v),
389+
InputValue::Float(v) => write!(f, "{}", v),
390+
InputValue::String(ref v) => write!(f, "\"{}\"", v),
391+
InputValue::Boolean(v) => write!(f, "{}", v),
392+
InputValue::Enum(ref v) => write!(f, "{}", v),
393+
InputValue::Variable(ref v) => write!(f, "${}", v),
394+
InputValue::List(ref v) => {
395+
try!(write!(f, "["));
396+
397+
for (i, spanning) in v.iter().enumerate() {
398+
try!(spanning.item.fmt(f));
399+
if i < v.len() - 1 { try!(write!(f, ", ")); }
400+
}
401+
402+
write!(f, "]")
403+
},
404+
InputValue::Object(ref o) => {
405+
try!(write!(f, "{{"));
406+
407+
for (i, &(ref k, ref v)) in o.iter().enumerate() {
408+
try!(write!(f, "{}: ", k.item));
409+
try!(v.item.fmt(f));
410+
if i < o.len() - 1 { try!(write!(f, ", ")); }
411+
}
412+
413+
write!(f, "}}")
414+
}
415+
}
417416
}
418417
}
419418

@@ -448,3 +447,44 @@ impl<'a> VariableDefinitions<'a> {
448447
self.items.iter()
449448
}
450449
}
450+
451+
#[cfg(test)]
452+
mod tests {
453+
use super::InputValue;
454+
use parser::Spanning;
455+
456+
#[test]
457+
fn test_input_value_fmt() {
458+
let value = InputValue::null();
459+
assert_eq!(format!("{}", value), "null");
460+
461+
let value = InputValue::int(123);
462+
assert_eq!(format!("{}", value), "123");
463+
464+
let value = InputValue::float(12.3);
465+
assert_eq!(format!("{}", value), "12.3");
466+
467+
let value = InputValue::string("FOO".to_owned());
468+
assert_eq!(format!("{}", value), "\"FOO\"");
469+
470+
let value = InputValue::boolean(true);
471+
assert_eq!(format!("{}", value), "true");
472+
473+
let value = InputValue::enum_value("BAR".to_owned());
474+
assert_eq!(format!("{}", value), "BAR");
475+
476+
let value = InputValue::variable("baz".to_owned());
477+
assert_eq!(format!("{}", value), "$baz");
478+
479+
let list = vec![InputValue::int(1), InputValue::int(2)];
480+
let value = InputValue::list(list);
481+
assert_eq!(format!("{}", value), "[1, 2]");
482+
483+
let object = vec![
484+
(Spanning::unlocated("foo".to_owned()), Spanning::unlocated(InputValue::int(1))),
485+
(Spanning::unlocated("bar".to_owned()), Spanning::unlocated(InputValue::int(2))),
486+
];
487+
let value = InputValue::parsed_object(object);
488+
assert_eq!(format!("{}", value), "{foo: 1, bar: 2}");
489+
}
490+
}

src/integrations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
#[cfg(feature="iron-handlers")] pub mod iron_handlers;
2+
#[cfg(feature="rustc-serialize")] pub mod rustc_serialize;
23
#[cfg(feature="serde")] pub mod serde;

src/integrations/rustc_serialize.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
use rustc_serialize::json::{ToJson, Json};
2+
3+
use ::{GraphQLError, Value};
4+
use ast::InputValue;
5+
use executor::ExecutionError;
6+
use parser::{ParseError, Spanning, SourcePosition};
7+
use validation::RuleError;
8+
9+
fn parse_error_to_json(err: &Spanning<ParseError>) -> Json {
10+
Json::Array(vec![
11+
Json::Object(vec![
12+
("message".to_owned(), format!("{}", err.item).to_json()),
13+
("locations".to_owned(), vec![
14+
Json::Object(vec![
15+
("line".to_owned(), (err.start.line() + 1).to_json()),
16+
("column".to_owned(), (err.start.column() + 1).to_json())
17+
].into_iter().collect()),
18+
].to_json()),
19+
].into_iter().collect()),
20+
])
21+
}
22+
23+
impl ToJson for ExecutionError {
24+
fn to_json(&self) -> Json {
25+
Json::Object(vec![
26+
("message".to_owned(), self.message().to_json()),
27+
("locations".to_owned(), vec![self.location().clone()].to_json()),
28+
("path".to_owned(), self.path().to_json()),
29+
].into_iter().collect())
30+
}
31+
}
32+
33+
impl<'a> ToJson for GraphQLError<'a> {
34+
fn to_json(&self) -> Json {
35+
match *self {
36+
GraphQLError::ParseError(ref err) => parse_error_to_json(err),
37+
GraphQLError::ValidationError(ref errs) => errs.to_json(),
38+
GraphQLError::MultipleOperationsProvided => Json::String(
39+
"Must provide operation name if query contains multiple operations".to_owned()),
40+
GraphQLError::NoOperationProvided => Json::String(
41+
"Must provide an operation".to_owned()),
42+
GraphQLError::UnknownOperationName => Json::String(
43+
"Unknown operation".to_owned()),
44+
}
45+
}
46+
}
47+
48+
impl ToJson for InputValue {
49+
fn to_json(&self) -> Json {
50+
match *self {
51+
InputValue::Null | InputValue::Variable(_) => Json::Null,
52+
InputValue::Int(i) => Json::I64(i),
53+
InputValue::Float(f) => Json::F64(f),
54+
InputValue::String(ref s) | InputValue::Enum(ref s) => Json::String(s.clone()),
55+
InputValue::Boolean(b) => Json::Boolean(b),
56+
InputValue::List(ref l) => Json::Array(l.iter().map(|x| x.item.to_json()).collect()),
57+
InputValue::Object(ref o) => Json::Object(o.iter().map(|&(ref k, ref v)| (k.item.clone(), v.item.to_json())).collect()),
58+
}
59+
}
60+
}
61+
62+
impl InputValue {
63+
/// Convert a `Json` structure into an `InputValue`.
64+
///
65+
/// This consumes the JSON instance.
66+
///
67+
/// Notes:
68+
/// * No enums or variables will be produced by this method.
69+
/// * All lists and objects will be unlocated
70+
pub fn from_json(json: Json) -> InputValue {
71+
match json {
72+
Json::I64(i) => InputValue::int(i),
73+
Json::U64(u) => InputValue::float(u as f64),
74+
Json::F64(f) => InputValue::float(f),
75+
Json::String(s) => InputValue::string(s),
76+
Json::Boolean(b) => InputValue::boolean(b),
77+
Json::Array(a) => InputValue::list(a.into_iter().map(InputValue::from_json).collect()),
78+
Json::Object(o) => InputValue::object(o.into_iter().map(|(k, v)| (k, InputValue::from_json(v))).collect()),
79+
Json::Null => InputValue::null(),
80+
}
81+
}
82+
}
83+
84+
impl ToJson for RuleError {
85+
fn to_json(&self) -> Json {
86+
Json::Object(vec![
87+
("message".to_owned(), self.message().to_json()),
88+
("locations".to_owned(), self.locations().to_json()),
89+
].into_iter().collect())
90+
}
91+
}
92+
93+
impl ToJson for SourcePosition {
94+
fn to_json(&self) -> Json {
95+
Json::Object(vec![
96+
("line".to_owned(), (self.line() + 1).to_json()),
97+
("column".to_owned(), (self.column() + 1).to_json()),
98+
].into_iter().collect())
99+
}
100+
}
101+
102+
impl ToJson for Value {
103+
fn to_json(&self) -> Json {
104+
match *self {
105+
Value::Null => Json::Null,
106+
Value::Int(i) => Json::I64(i),
107+
Value::Float(f) => Json::F64(f),
108+
Value::String(ref s) => Json::String(s.clone()),
109+
Value::Boolean(b) => Json::Boolean(b),
110+
Value::List(ref l) => Json::Array(l.iter().map(|x| x.to_json()).collect()),
111+
Value::Object(ref o) => Json::Object(o.iter().map(|(k,v)| (k.clone(), v.to_json())).collect()),
112+
}
113+
}
114+
}

src/lib.rs

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ built-in [GraphiQL][6] handler included.
186186
#![cfg_attr(feature="nightly", feature(test))]
187187
#![warn(missing_docs)]
188188

189-
extern crate rustc_serialize;
189+
#[cfg(feature="rustc-serialize")] extern crate rustc_serialize;
190190
#[cfg(feature="serde")] extern crate serde;
191191

192192
#[cfg(feature="nightly")] extern crate test;
@@ -211,9 +211,7 @@ mod integrations;
211211

212212
use std::collections::HashMap;
213213

214-
use rustc_serialize::json::{ToJson, Json};
215-
216-
use parser::{parse_document_source, ParseError, Spanning, SourcePosition};
214+
use parser::{parse_document_source, ParseError, Spanning};
217215
use validation::{ValidatorContext, visit_all_rules, validate_input_values};
218216
use executor::execute_validated_query;
219217

@@ -285,63 +283,6 @@ impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
285283
}
286284
}
287285

288-
impl<'a> ToJson for GraphQLError<'a> {
289-
fn to_json(&self) -> Json {
290-
match *self {
291-
GraphQLError::ParseError(ref err) => parse_error_to_json(err),
292-
GraphQLError::ValidationError(ref errs) => errs.to_json(),
293-
GraphQLError::MultipleOperationsProvided => Json::String(
294-
"Must provide operation name if query contains multiple operations".to_owned()),
295-
GraphQLError::NoOperationProvided => Json::String(
296-
"Must provide an operation".to_owned()),
297-
GraphQLError::UnknownOperationName => Json::String(
298-
"Unknown operation".to_owned()),
299-
}
300-
}
301-
}
302-
303-
fn parse_error_to_json(err: &Spanning<ParseError>) -> Json {
304-
Json::Array(vec![
305-
Json::Object(vec![
306-
("message".to_owned(), format!("{}", err.item).to_json()),
307-
("locations".to_owned(), vec![
308-
Json::Object(vec![
309-
("line".to_owned(), (err.start.line() + 1).to_json()),
310-
("column".to_owned(), (err.start.column() + 1).to_json())
311-
].into_iter().collect()),
312-
].to_json()),
313-
].into_iter().collect()),
314-
])
315-
}
316-
317-
impl ToJson for RuleError {
318-
fn to_json(&self) -> Json {
319-
Json::Object(vec![
320-
("message".to_owned(), self.message().to_json()),
321-
("locations".to_owned(), self.locations().to_json()),
322-
].into_iter().collect())
323-
}
324-
}
325-
326-
impl ToJson for SourcePosition {
327-
fn to_json(&self) -> Json {
328-
Json::Object(vec![
329-
("line".to_owned(), (self.line() + 1).to_json()),
330-
("column".to_owned(), (self.column() + 1).to_json()),
331-
].into_iter().collect())
332-
}
333-
}
334-
335-
impl ToJson for ExecutionError {
336-
fn to_json(&self) -> Json {
337-
Json::Object(vec![
338-
("message".to_owned(), self.message().to_json()),
339-
("locations".to_owned(), vec![self.location().clone()].to_json()),
340-
("path".to_owned(), self.path().to_json()),
341-
].into_iter().collect())
342-
}
343-
}
344-
345286
#[doc(hidden)]
346287
pub fn to_camel_case(s: &str) -> String {
347288
let mut dest = String::new();

src/schema/schema.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use rustc_serialize::json::ToJson;
2-
31
use types::base::{GraphQLType, Arguments, TypeKind};
42
use executor::{Executor, Registry, ExecutionResult};
53

@@ -191,7 +189,7 @@ graphql_object!(<'a> Argument<'a>: SchemaType<'a> as "__InputValue" |&self| {
191189
}
192190

193191
field default_value() -> Option<String> {
194-
self.default_value.as_ref().map(|v| v.to_json().to_string())
192+
self.default_value.as_ref().map(|v| format!("{}", v))
195193
}
196194
});
197195

src/value.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use std::collections::HashMap;
22
use std::hash::Hash;
33

4-
use rustc_serialize::json::{ToJson, Json};
5-
64
use parser::Spanning;
75
use ast::{InputValue, ToInputValue};
86

@@ -100,20 +98,6 @@ impl Value {
10098
}
10199
}
102100

103-
impl ToJson for Value {
104-
fn to_json(&self) -> Json {
105-
match *self {
106-
Value::Null => Json::Null,
107-
Value::Int(i) => Json::I64(i),
108-
Value::Float(f) => Json::F64(f),
109-
Value::String(ref s) => Json::String(s.clone()),
110-
Value::Boolean(b) => Json::Boolean(b),
111-
Value::List(ref l) => Json::Array(l.iter().map(|x| x.to_json()).collect()),
112-
Value::Object(ref o) => Json::Object(o.iter().map(|(k,v)| (k.clone(), v.to_json())).collect()),
113-
}
114-
}
115-
}
116-
117101
impl ToInputValue for Value {
118102
fn to(&self) -> InputValue {
119103
match *self {

0 commit comments

Comments
 (0)