Implements `ScalarType` for `serde_json::Value`.

This commit is contained in:
Sunli 2021-04-01 16:54:54 +08:00
parent 9eff268321
commit 40549303d4
4 changed files with 29 additions and 10 deletions

View File

@ -8,6 +8,7 @@ nd this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.
- Add cache support for DataLoader. [#455](https://github.com/async-graphql/async-graphql/issues/455)
- Prevent Warp WS Close, Ping, and Pong messages from being parsed as GraphQL [#459](https://github.com/async-graphql/async-graphql/pull/459)
- Implements `ScalarType` for `serde_json::Value`.
## [2.7.2]

View File

@ -85,6 +85,8 @@ struct Requests<K: Send + Sync + Hash + Eq + Clone + 'static, T: Loader<K>> {
cache_storage: Box<dyn CacheStorage<Key = K, Value = T::Value>>,
}
type KeysAndSender<K, T> = (HashSet<K>, Vec<(HashSet<K>, ResSender<K, T>)>);
impl<K: Send + Sync + Hash + Eq + Clone + 'static, T: Loader<K>> Requests<K, T> {
fn new<C: CacheFactory>(cache_factory: &C) -> Self {
Self {
@ -94,7 +96,7 @@ impl<K: Send + Sync + Hash + Eq + Clone + 'static, T: Loader<K>> Requests<K, T>
}
}
fn take(&mut self) -> (HashSet<K>, Vec<(HashSet<K>, ResSender<K, T>)>) {
fn take(&mut self) -> KeysAndSender<K, T> {
(
std::mem::take(&mut self.keys),
std::mem::take(&mut self.pending),

View File

@ -119,9 +119,10 @@ impl<T: Tracer + Send + Sync> Extension for OpenTelemetryExtension<T> {
variables: &Variables,
) {
if let Some(parent_cx) = self.contexts.get(&REQUEST_CTX).cloned() {
let mut attributes = Vec::with_capacity(2);
attributes.push(KEY_SOURCE.string(query_source.to_string()));
attributes.push(KEY_VARIABLES.string(serde_json::to_string(variables).unwrap()));
let attributes = vec![
KEY_SOURCE.string(query_source.to_string()),
KEY_VARIABLES.string(serde_json::to_string(variables).unwrap()),
];
let parse_span = self
.tracer
.span_builder("parse")
@ -189,10 +190,11 @@ impl<T: Tracer + Send + Sync> Extension for OpenTelemetryExtension<T> {
.cloned();
if let Some(parent_cx) = parent_cx {
let mut attributes = Vec::with_capacity(3);
attributes.push(KEY_RESOLVE_ID.i64(info.resolve_id.current as i64));
attributes.push(KEY_PARENT_TYPE.string(info.parent_type.to_string()));
attributes.push(KEY_RETURN_TYPE.string(info.return_type.to_string()));
let attributes = vec![
KEY_RESOLVE_ID.i64(info.resolve_id.current as i64),
KEY_PARENT_TYPE.string(info.parent_type.to_string()),
KEY_RETURN_TYPE.string(info.return_type.to_string()),
];
let span = self
.tracer
.span_builder(&info.path_node.to_string())

View File

@ -7,8 +7,8 @@ use serde::{Deserialize, Serialize};
use crate::parser::types::Field;
use crate::registry::{MetaType, Registry};
use crate::{
from_value, to_value, ContextSelectionSet, InputValueResult, OutputType, Positioned, Scalar,
ScalarType, ServerResult, Type, Value,
from_value, to_value, ContextSelectionSet, InputValueError, InputValueResult, OutputType,
Positioned, Scalar, ScalarType, ServerResult, Type, Value,
};
/// A scalar that can represent any JSON value.
@ -100,6 +100,20 @@ impl<T: Serialize + Send + Sync> OutputType for OutputJson<T> {
}
}
/// A scalar that can represent any JSON value.
#[Scalar(internal, name = "JSON")]
impl ScalarType for serde_json::Value {
fn parse(value: Value) -> InputValueResult<Self> {
value
.into_json()
.map_err(|_| InputValueError::custom("Invalid JSON"))
}
fn to_value(&self) -> Value {
Value::from_json(self.clone()).unwrap_or_default()
}
}
#[cfg(test)]
mod test {
use crate::*;