Clean up crate root and improve context
This commit is contained in:
parent
2671e45015
commit
ccae2d4ef5
|
@ -1,10 +1,11 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::parser::types::Field;
|
||||
use crate::registry::Registry;
|
||||
use crate::{
|
||||
registry, ContainerType, ContextSelectionSet, InputValueResult, Positioned, Result,
|
||||
ServerResult, Value,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Represents a GraphQL type.
|
||||
///
|
||||
|
|
114
src/context.rs
114
src/context.rs
|
@ -1,3 +1,17 @@
|
|||
//! Query context.
|
||||
|
||||
use std::any::{Any, TypeId};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
use std::ops::Deref;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
|
||||
use fnv::FnvHashMap;
|
||||
use serde::ser::{SerializeSeq, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::extensions::Extensions;
|
||||
use crate::parser::types::{
|
||||
Directive, Field, FragmentDefinition, OperationDefinition, SelectionSet,
|
||||
|
@ -8,16 +22,6 @@ use crate::{
|
|||
UploadValue, Value,
|
||||
};
|
||||
use async_graphql_value::{Name, Value as InputValue};
|
||||
use fnv::FnvHashMap;
|
||||
use serde::ser::{SerializeSeq, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::any::{Any, TypeId};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
use std::ops::Deref;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Variables of a query.
|
||||
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
|
||||
|
@ -119,22 +123,27 @@ pub type ContextSelectionSet<'a> = ContextBase<'a, &'a Positioned<SelectionSet>>
|
|||
/// Context object for resolve field
|
||||
pub type Context<'a> = ContextBase<'a, &'a Positioned<Field>>;
|
||||
|
||||
/// The query path segment
|
||||
#[derive(Clone)]
|
||||
/// A segment in the path to the current query.
|
||||
///
|
||||
/// This is a borrowed form of [`PathSegment`](enum.PathSegment.html) used during execution instead
|
||||
/// of passed back when errors occur.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum QueryPathSegment<'a> {
|
||||
/// Index
|
||||
/// We are currently resolving an element in a list.
|
||||
Index(usize),
|
||||
/// Field name
|
||||
/// We are currently resolving a field in an object.
|
||||
Name(&'a str),
|
||||
}
|
||||
|
||||
/// The query path node
|
||||
#[derive(Clone)]
|
||||
/// A path to the current query.
|
||||
///
|
||||
/// The path is stored as a kind of reverse linked list.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct QueryPathNode<'a> {
|
||||
/// Parent node
|
||||
/// The parent node to this, if there is one.
|
||||
pub parent: Option<&'a QueryPathNode<'a>>,
|
||||
|
||||
/// Current path segment
|
||||
/// The current path segment being resolved.
|
||||
pub segment: QueryPathSegment<'a>,
|
||||
}
|
||||
|
||||
|
@ -176,26 +185,31 @@ impl<'a> Display for QueryPathNode<'a> {
|
|||
|
||||
impl<'a> QueryPathNode<'a> {
|
||||
/// Get the current field name.
|
||||
///
|
||||
/// This traverses all the parents of the node until it finds one that is a field name.
|
||||
pub fn field_name(&self) -> &str {
|
||||
let mut p = self;
|
||||
loop {
|
||||
if let QueryPathSegment::Name(name) = &p.segment {
|
||||
return name;
|
||||
}
|
||||
p = p.parent.unwrap();
|
||||
}
|
||||
self.parents().find_map(|node| match node.segment {
|
||||
QueryPathSegment::Name(name) => Some(name),
|
||||
QueryPathSegment::Index(_) => None,
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
/// Get the path represented by `Vec<String>`.
|
||||
/// Get the path represented by `Vec<String>`; numbers will be stringified.
|
||||
#[must_use]
|
||||
pub fn to_string_vec(&self) -> Vec<String> {
|
||||
let mut res = Vec::new();
|
||||
self.for_each(|s| match s {
|
||||
QueryPathSegment::Index(idx) => res.push(format!("{}", idx)),
|
||||
QueryPathSegment::Name(name) => res.push(name.to_string()),
|
||||
});
|
||||
self.for_each(|s| res.push(match s {
|
||||
QueryPathSegment::Name(name) => name.to_string(),
|
||||
QueryPathSegment::Index(idx) => idx.to_string(),
|
||||
}));
|
||||
res
|
||||
}
|
||||
|
||||
/// Iterate over the parents of the node.
|
||||
pub fn parents(&self) -> Parents<'_> {
|
||||
Parents(self)
|
||||
}
|
||||
|
||||
pub(crate) fn for_each<F: FnMut(&QueryPathSegment<'a>)>(&self, mut f: F) {
|
||||
self.for_each_ref(&mut f);
|
||||
}
|
||||
|
@ -208,13 +222,39 @@ impl<'a> QueryPathNode<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents the unique id of the resolve
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
/// An iterator over the parents of a [`QueryPathNode`](struct.QueryPathNode.html).
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Parents<'a>(&'a QueryPathNode<'a>);
|
||||
|
||||
impl<'a> Parents<'a> {
|
||||
/// Get the current query path node, which the next call to `next` will get the parents of.
|
||||
#[must_use]
|
||||
pub fn current(&self) -> &'a QueryPathNode<'a> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Parents<'a> {
|
||||
type Item = &'a QueryPathNode<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let parent = self.0.parent;
|
||||
if let Some(parent) = parent {
|
||||
self.0 = parent;
|
||||
}
|
||||
parent
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::FusedIterator for Parents<'a> {}
|
||||
|
||||
/// The unique id of the current resolusion.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ResolveId {
|
||||
/// Parent id
|
||||
/// The unique ID of the parent resolution.
|
||||
pub parent: Option<usize>,
|
||||
|
||||
/// Current id
|
||||
/// The current unique id.
|
||||
pub current: usize,
|
||||
}
|
||||
|
||||
|
@ -238,7 +278,9 @@ impl Display for ResolveId {
|
|||
}
|
||||
}
|
||||
|
||||
/// Query context
|
||||
/// Query context.
|
||||
///
|
||||
/// **This type is not stable and should not be used directly.**
|
||||
#[derive(Clone)]
|
||||
pub struct ContextBase<'a, T> {
|
||||
#[allow(missing_docs)]
|
||||
|
@ -338,7 +380,7 @@ impl<'a, T> ContextBase<'a, T> {
|
|||
selection_set: &'a Positioned<SelectionSet>,
|
||||
) -> ContextBase<'a, &'a Positioned<SelectionSet>> {
|
||||
ContextBase {
|
||||
path_node: self.path_node.clone(),
|
||||
path_node: self.path_node,
|
||||
item: selection_set,
|
||||
resolve_id: self.resolve_id,
|
||||
inc_resolve_id: &self.inc_resolve_id,
|
||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -113,7 +113,6 @@
|
|||
#![cfg_attr(feature = "nightly", feature(doc_cfg))]
|
||||
|
||||
mod base;
|
||||
mod context;
|
||||
mod error;
|
||||
mod look_ahead;
|
||||
mod model;
|
||||
|
@ -124,6 +123,7 @@ mod subscription;
|
|||
mod validation;
|
||||
|
||||
pub mod extensions;
|
||||
pub mod context;
|
||||
pub mod guard;
|
||||
pub mod http;
|
||||
pub mod resolver_utils;
|
||||
|
@ -156,9 +156,6 @@ pub use async_graphql_value::{
|
|||
pub use base::{
|
||||
InputObjectType, InputValueType, InterfaceType, ObjectType, OutputValueType, Type, UnionType,
|
||||
};
|
||||
pub use context::{
|
||||
Context, ContextBase, Data, QueryEnv, QueryPathNode, QueryPathSegment, ResolveId, Variables,
|
||||
};
|
||||
pub use error::{
|
||||
Error, ErrorExtensionValues, ErrorExtensions, InputValueError, InputValueResult,
|
||||
ParseRequestError, PathSegment, Result, ResultExt, ServerError, ServerResult,
|
||||
|
@ -166,21 +163,25 @@ pub use error::{
|
|||
pub use look_ahead::Lookahead;
|
||||
pub use registry::CacheControl;
|
||||
pub use request::{BatchRequest, Request};
|
||||
#[doc(no_inline)]
|
||||
pub use resolver_utils::{ContainerType, EnumType, ScalarType};
|
||||
pub use response::{BatchResponse, Response};
|
||||
pub use schema::{Schema, SchemaBuilder, SchemaEnv};
|
||||
pub use validation::ValidationMode;
|
||||
|
||||
/// An alias of [async_graphql::Error](struct.Error.html).
|
||||
pub type FieldError = Error;
|
||||
|
||||
/// An alias of [async_graphql::Result](type.Result.html).
|
||||
pub type FieldResult<T> = Result<T>;
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use parser::{Pos, Positioned};
|
||||
pub use context::*;
|
||||
pub use types::*;
|
||||
|
||||
/// An alias of [async_graphql::Error](struct.Error.html). Present for backward compatibility
|
||||
/// reasons.
|
||||
pub type FieldError = Error;
|
||||
|
||||
/// An alias of [async_graphql::Result](type.Result.html). Present for backward compatibility
|
||||
/// reasons.
|
||||
pub type FieldResult<T> = Result<T>;
|
||||
|
||||
/// Define a GraphQL object with methods
|
||||
///
|
||||
/// *[See also the Book](https://async-graphql.github.io/async-graphql/en/define_complex_object.html).*
|
||||
|
|
Loading…
Reference in New Issue
Block a user