Skip to content

Commit fce45ec

Browse files
authored
Merge pull request #8 from zaeleus/serde
Add optional Serde serialization support
2 parents 0e65a20 + aa056dd commit fce45ec

File tree

4 files changed

+209
-0
lines changed

4 files changed

+209
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ expose-test-schema = []
2323
[dependencies]
2424
rustc-serialize = "^0.3.19"
2525
iron = { version = "^0.4.0", optional = true }
26+
serde = { version = "^0.8.21", optional = true }
2627

2728
[dev-dependencies]
2829
iron = "^0.4.0"

src/integrations/mod.rs

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

src/integrations/serde.rs

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
use serde::{de, ser};
2+
use std::collections::HashMap;
3+
4+
use ::{GraphQLError, Value};
5+
use ast::InputValue;
6+
use executor::ExecutionError;
7+
use parser::{ParseError, Spanning, SourcePosition};
8+
use validation::RuleError;
9+
10+
impl ser::Serialize for ExecutionError {
11+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
12+
where S: ser::Serializer,
13+
{
14+
let mut state = try!(serializer.serialize_map(Some(3)));
15+
16+
try!(serializer.serialize_map_key(&mut state, "message"));
17+
try!(serializer.serialize_map_value(&mut state, self.message()));
18+
19+
try!(serializer.serialize_map_key(&mut state, "locations"));
20+
try!(serializer.serialize_map_value(&mut state, vec![self.location()]));
21+
22+
try!(serializer.serialize_map_key(&mut state, "path"));
23+
try!(serializer.serialize_map_value(&mut state, self.path()));
24+
25+
serializer.serialize_map_end(state)
26+
}
27+
}
28+
29+
impl<'a> ser::Serialize for GraphQLError<'a> {
30+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
31+
where S: ser::Serializer,
32+
{
33+
match *self {
34+
GraphQLError::ParseError(ref err) => vec![err].serialize(serializer),
35+
GraphQLError::ValidationError(ref errs) => errs.serialize(serializer),
36+
GraphQLError::NoOperationProvided => {
37+
serializer.serialize_str("Must provide an operation")
38+
},
39+
GraphQLError::MultipleOperationsProvided => {
40+
serializer.serialize_str("Must provide operation name if query contains multiple operations")
41+
},
42+
GraphQLError::UnknownOperationName => {
43+
serializer.serialize_str("Unknown operation")
44+
},
45+
}
46+
}
47+
}
48+
49+
impl de::Deserialize for InputValue {
50+
fn deserialize<D>(deserializer: &mut D) -> Result<InputValue, D::Error>
51+
where D: de::Deserializer,
52+
{
53+
struct InputValueVisitor;
54+
55+
impl de::Visitor for InputValueVisitor {
56+
type Value = InputValue;
57+
58+
fn visit_bool<E>(&mut self, value: bool) -> Result<InputValue, E> {
59+
Ok(InputValue::boolean(value))
60+
}
61+
62+
fn visit_i64<E>(&mut self, value: i64) -> Result<InputValue, E> {
63+
Ok(InputValue::int(value))
64+
}
65+
66+
fn visit_u64<E>(&mut self, value: u64) -> Result<InputValue, E>
67+
where E: de::Error,
68+
{
69+
self.visit_f64(value as f64)
70+
}
71+
72+
fn visit_f64<E>(&mut self, value: f64) -> Result<InputValue, E> {
73+
Ok(InputValue::float(value))
74+
}
75+
76+
fn visit_str<E>(&mut self, value: &str) -> Result<InputValue, E>
77+
where E: de::Error,
78+
{
79+
self.visit_string(value.into())
80+
}
81+
82+
fn visit_string<E>(&mut self, value: String) -> Result<InputValue, E> {
83+
Ok(InputValue::string(value))
84+
}
85+
86+
fn visit_none<E>(&mut self) -> Result<InputValue, E> {
87+
Ok(InputValue::null())
88+
}
89+
90+
fn visit_unit<E>(&mut self) -> Result<InputValue, E> {
91+
Ok(InputValue::null())
92+
}
93+
94+
fn visit_seq<V>(&mut self, visitor: V) -> Result<InputValue, V::Error>
95+
where V: de::SeqVisitor,
96+
{
97+
let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
98+
Ok(InputValue::list(values))
99+
}
100+
101+
fn visit_map<V>(&mut self, visitor: V) -> Result<InputValue, V::Error>
102+
where V: de::MapVisitor,
103+
{
104+
let values = try!(de::impls::HashMapVisitor::<String, InputValue, _>::new()
105+
.visit_map(visitor));
106+
Ok(InputValue::object(values))
107+
}
108+
}
109+
110+
deserializer.deserialize(InputValueVisitor)
111+
}
112+
}
113+
114+
impl ser::Serialize for InputValue {
115+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
116+
where S: ser::Serializer,
117+
{
118+
match *self {
119+
InputValue::Null | InputValue::Variable(_) => serializer.serialize_unit(),
120+
InputValue::Int(v) => serializer.serialize_i64(v),
121+
InputValue::Float(v) => serializer.serialize_f64(v),
122+
InputValue::String(ref v) | InputValue::Enum(ref v) => serializer.serialize_str(v),
123+
InputValue::Boolean(v) => serializer.serialize_bool(v),
124+
InputValue::List(ref v) => {
125+
v.iter().map(|x| x.item.clone()).collect::<Vec<_>>().serialize(serializer)
126+
},
127+
InputValue::Object(ref v) => {
128+
v.iter()
129+
.map(|&(ref k, ref v)| (k.item.clone(), v.item.clone()))
130+
.collect::<HashMap<_, _>>()
131+
.serialize(serializer)
132+
},
133+
}
134+
}
135+
}
136+
137+
impl ser::Serialize for RuleError {
138+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
139+
where S: ser::Serializer,
140+
{
141+
let mut state = try!(serializer.serialize_map(Some(2)));
142+
143+
try!(serializer.serialize_map_key(&mut state, "message"));
144+
try!(serializer.serialize_map_value(&mut state, self.message()));
145+
146+
try!(serializer.serialize_map_key(&mut state, "locations"));
147+
try!(serializer.serialize_map_value(&mut state, self.locations()));
148+
149+
serializer.serialize_map_end(state)
150+
}
151+
}
152+
153+
impl ser::Serialize for SourcePosition {
154+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
155+
where S: ser::Serializer,
156+
{
157+
let mut state = try!(serializer.serialize_map(Some(2)));
158+
159+
try!(serializer.serialize_map_key(&mut state, "line"));
160+
try!(serializer.serialize_map_value(&mut state, self.line() + 1));
161+
162+
try!(serializer.serialize_map_key(&mut state, "column"));
163+
try!(serializer.serialize_map_value(&mut state, self.column() + 1));
164+
165+
serializer.serialize_map_end(state)
166+
}
167+
}
168+
169+
impl<'a> ser::Serialize for Spanning<ParseError<'a>> {
170+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
171+
where S: ser::Serializer,
172+
{
173+
let mut state = try!(serializer.serialize_map(Some(2)));
174+
175+
let message = format!("{}", self.item);
176+
try!(serializer.serialize_map_key(&mut state, "message"));
177+
try!(serializer.serialize_map_value(&mut state, message));
178+
179+
let mut location = HashMap::new();
180+
location.insert("line".to_owned(), self.start.line() + 1);
181+
location.insert("column".to_owned(), self.start.column() + 1);
182+
183+
let locations = vec![location];
184+
185+
try!(serializer.serialize_map_key(&mut state, "locations"));
186+
try!(serializer.serialize_map_value(&mut state, locations));
187+
188+
serializer.serialize_map_end(state)
189+
}
190+
}
191+
192+
impl ser::Serialize for Value {
193+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
194+
where S: ser::Serializer,
195+
{
196+
match *self {
197+
Value::Null => serializer.serialize_unit(),
198+
Value::Int(v) => serializer.serialize_i64(v),
199+
Value::Float(v) => serializer.serialize_f64(v),
200+
Value::String(ref v) => serializer.serialize_str(v),
201+
Value::Boolean(v) => serializer.serialize_bool(v),
202+
Value::List(ref v) => v.serialize(serializer),
203+
Value::Object(ref v) => v.serialize(serializer),
204+
}
205+
}
206+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ built-in [GraphiQL][6] handler included.
187187
#![warn(missing_docs)]
188188

189189
extern crate rustc_serialize;
190+
#[cfg(feature="serde")] extern crate serde;
190191

191192
#[cfg(feature="nightly")] extern crate test;
192193
#[cfg(feature="iron-handlers")] #[macro_use(itry, iexpect)] extern crate iron;

0 commit comments

Comments
 (0)