Skip to content

Commit d2bdcd9

Browse files
committed
feat: add GraphQLValueAsync impl for serde_json
1 parent 86a60c1 commit d2bdcd9

File tree

1 file changed

+92
-10
lines changed

1 file changed

+92
-10
lines changed

juniper/src/integrations/json.rs

Lines changed: 92 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use graphql_parser::{
88
use juniper::{
99
meta::{Field, MetaType},
1010
Arguments, ExecutionResult, Executor, FieldError, GraphQLType, GraphQLValue, Registry,
11-
ScalarValue, Selection, Value,
11+
ScalarValue, Selection, Value, GraphQLValueAsync, BoxFuture,
1212
};
1313
use serde_json::Value as Json;
1414

15-
use crate::{types::base::resolve_selection_set_into, GraphQLValueAsync};
15+
use crate::{types::base::resolve_selection_set_into};
1616

1717
// Used to describe the graphql type of a `serde_json::Value` using the GraphQL
1818
// schema definition language.
@@ -29,8 +29,8 @@ pub struct TypeInfo {
2929

3030
impl TypeInfo {
3131
fn meta<'r, S>(&self, registry: &mut Registry<'r, S>) -> MetaType<'r, S>
32-
where
33-
S: ScalarValue + 'r,
32+
where
33+
S: ScalarValue + 'r,
3434
{
3535
let mut fields = Vec::new();
3636
let s = self.schema.clone().unwrap_or_default();
@@ -67,9 +67,9 @@ impl TypeInfo {
6767
type_ref: Type<'t, T>,
6868
nullable: bool,
6969
) -> Field<'r, S>
70-
where
71-
S: 'r + ScalarValue,
72-
T: Text<'t>,
70+
where
71+
S: 'r + ScalarValue,
72+
T: Text<'t>,
7373
{
7474
match type_ref {
7575
Type::NamedType(type_name) => match type_name.as_ref() {
@@ -115,7 +115,11 @@ impl TypeInfo {
115115
},
116116
Type::ListType(nested_type) => {
117117
let mut field = self.build_field(registry, field_name, *nested_type, true);
118-
field.field_type = juniper::Type::List(Box::new(field.field_type), None);
118+
if nullable {
119+
field.field_type = juniper::Type::List(Box::new(field.field_type), None);
120+
} else {
121+
field.field_type = juniper::Type::NonNullList(Box::new(field.field_type), None);
122+
}
119123
field
120124
}
121125
Type::NonNullType(nested_type) => {
@@ -131,8 +135,8 @@ impl<S: ScalarValue> GraphQLType<S> for Json {
131135
}
132136

133137
fn meta<'r>(info: &Self::TypeInfo, registry: &mut Registry<'r, S>) -> MetaType<'r, S>
134-
where
135-
S: 'r,
138+
where
139+
S: 'r,
136140
{
137141
info.meta(registry)
138142
}
@@ -225,6 +229,38 @@ impl<S: ScalarValue> GraphQLValue<S> for Json {
225229
}
226230
}
227231

232+
233+
impl<S> GraphQLValueAsync<S> for Json
234+
where
235+
Self::TypeInfo: Sync,
236+
Self::Context: Sync,
237+
S: ScalarValue + Send + Sync,
238+
{
239+
fn resolve_async<'a>(
240+
&'a self,
241+
info: &'a Self::TypeInfo,
242+
selection_set: Option<&'a [Selection<S>]>,
243+
executor: &'a Executor<Self::Context, S>,
244+
) -> BoxFuture<'a, ExecutionResult<S>> {
245+
Box::pin(async move {
246+
<Json as GraphQLValue<S>>::resolve(self, info, selection_set, executor)
247+
})
248+
}
249+
250+
fn resolve_field_async<'a>(
251+
&'a self,
252+
info: &'a Self::TypeInfo,
253+
field_name: &'a str,
254+
arguments: &'a Arguments<S>,
255+
executor: &'a Executor<Self::Context, S>,
256+
) -> BoxFuture<'a, ExecutionResult<S>> {
257+
Box::pin(async move {
258+
<Json as GraphQLValue<S>>::resolve_field(self, info, field_name, arguments, executor)
259+
})
260+
}
261+
}
262+
263+
228264
#[cfg(test)]
229265
mod tests {
230266
use juniper::{
@@ -422,4 +458,50 @@ mod tests {
422458
)),
423459
);
424460
}
461+
462+
#[tokio::test]
463+
async fn test_async() {
464+
let sdl = r#"
465+
type Query {
466+
hero: Hero
467+
}
468+
type Hero {
469+
id: String
470+
name: String
471+
}
472+
"#;
473+
let data = json!({
474+
"hero": {
475+
"id": "2001",
476+
"name": "R2-D2",
477+
},
478+
});
479+
480+
let schema: RootNode<_, _, _> = RootNode::new_with_info(
481+
data,
482+
EmptyMutation::new(),
483+
EmptySubscription::new(),
484+
TypeInfo {
485+
name: "Query".to_string(),
486+
schema: Some(sdl.to_string()),
487+
},
488+
(),
489+
(),
490+
);
491+
492+
let doc = r#"{
493+
hero {
494+
id
495+
name
496+
}
497+
}"#;
498+
assert_eq!(
499+
crate::execute(doc, None, &schema, &Variables::new(), &()).await,
500+
Ok((
501+
graphql_value!({"hero": {"id": "2001", "name": "R2-D2"}}),
502+
vec![],
503+
)),
504+
);
505+
}
425506
}
507+

0 commit comments

Comments
 (0)