Add data_XXX methods to ResolveInfo and remove context field from ResolveInfo. #260

This commit is contained in:
Sunli 2020-09-25 15:26:29 +08:00
parent 8a82954f0b
commit b316c30416
4 changed files with 50 additions and 1 deletions

View File

@ -90,6 +90,14 @@ impl From<Variables> for Value {
#[derive(Default)]
pub struct Data(FnvHashMap<TypeId, Box<dyn Any + Sync + Send>>);
impl Deref for Data {
type Target = FnvHashMap<TypeId, Box<dyn Any + Sync + Send>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Data {
/// Insert data.
pub fn insert<D: Any + Send + Sync>(&mut self, data: D) {

View File

@ -8,7 +8,7 @@ mod logger;
mod tracing;
use crate::context::{QueryPathNode, ResolveId};
use crate::{Result, Variables};
use crate::{FieldResult, QueryEnv, Result, SchemaEnv, Variables};
#[cfg(feature = "apollo_tracing")]
pub use self::apollo_tracing::ApolloTracing;
@ -19,6 +19,7 @@ pub use self::tracing::Tracing;
use crate::parser::types::ExecutableDocument;
use crate::Error;
use serde_json::Value;
use std::any::{Any, TypeId};
pub(crate) type BoxExtension = Box<dyn Extension>;
@ -39,6 +40,42 @@ pub struct ResolveInfo<'a> {
/// Current return type, is qualified name.
pub return_type: &'a str,
pub(crate) schema_env: &'a SchemaEnv,
pub(crate) query_env: &'a QueryEnv,
}
impl<'a> ResolveInfo<'a> {
/// Gets the global data defined in the `Context` or `Schema`.
///
/// If both `Schema` and `Query` have the same data type, the data in the `Query` is obtained.
///
/// # Errors
///
/// Returns a `FieldError` if the specified type data does not exist.
pub fn data<D: Any + Send + Sync>(&self) -> FieldResult<&D> {
self.data_opt::<D>()
.ok_or_else(|| format!("Data `{}` does not exist.", std::any::type_name::<D>()).into())
}
/// Gets the global data defined in the `Context` or `Schema`.
///
/// # Panics
///
/// It will panic if the specified data type does not exist.
pub fn data_unchecked<D: Any + Send + Sync>(&self) -> &D {
self.data_opt::<D>()
.unwrap_or_else(|| panic!("Data `{}` does not exist.", std::any::type_name::<D>()))
}
/// Gets the global data defined in the `Context` or `Schema` or `None` if the specified type data does not exist.
pub fn data_opt<D: Any + Send + Sync>(&self) -> Option<&D> {
self.query_env
.ctx_data
.get(&TypeId::of::<D>())
.or_else(|| self.schema_env.data.get(&TypeId::of::<D>()))
.and_then(|d| d.downcast_ref::<D>())
}
}
/// Represents a GraphQL extension

View File

@ -18,6 +18,8 @@ pub async fn resolve_list<'a, T: OutputValueType + Send + Sync + 'a>(
path_node: ctx_idx.path_node.as_ref().unwrap(),
parent_type: &Vec::<T>::type_name(),
return_type: &T::type_name(),
schema_env: ctx.schema_env,
query_env: ctx.query_env,
};
ctx_idx

View File

@ -194,6 +194,8 @@ impl<'a> Fields<'a> {
})
}
},
schema_env: ctx.schema_env,
query_env: ctx.query_env,
};
ctx_field