Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
weiznich committed Aug 27, 2018
1 parent ec59766 commit 21ed215
Show file tree
Hide file tree
Showing 59 changed files with 2,911 additions and 1,855 deletions.
1 change: 1 addition & 0 deletions juniper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ fnv = "1.0.3"
indexmap = { version = "1.0.0", features = ["serde-1"] }
serde = { version = "1.0.8" }
serde_derive = { version = "1.0.2" }
erased-serde = "0.3"

chrono = { version = "0.4.0", optional = true }
serde_json = { version="1.0.2", optional = true }
Expand Down
157 changes: 86 additions & 71 deletions juniper/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fmt;
use std::hash::Hash;
use std::slice;
use std::vec;
use ScalarValue;

use indexmap::IndexMap;

Expand Down Expand Up @@ -37,54 +38,55 @@ pub enum Type<'a> {
/// their position in the source file, if available.
#[derive(Clone, PartialEq, Debug)]
#[allow(missing_docs)]
pub enum InputValue {
pub enum InputValue<S: fmt::Debug> {
Null,
Scalar(S),
Int(i32),
Float(f64),
String(String),
Boolean(bool),
Enum(String),
Variable(String),
List(Vec<Spanning<InputValue>>),
Object(Vec<(Spanning<String>, Spanning<InputValue>)>),
List(Vec<Spanning<InputValue<S>>>),
Object(Vec<(Spanning<String>, Spanning<InputValue<S>>)>),
}

#[derive(Clone, PartialEq, Debug)]
pub struct VariableDefinition<'a> {
pub struct VariableDefinition<'a, S: fmt::Debug> {
pub var_type: Spanning<Type<'a>>,
pub default_value: Option<Spanning<InputValue>>,
pub default_value: Option<Spanning<InputValue<S>>>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct Arguments<'a> {
pub items: Vec<(Spanning<&'a str>, Spanning<InputValue>)>,
pub struct Arguments<'a, S: fmt::Debug> {
pub items: Vec<(Spanning<&'a str>, Spanning<InputValue<S>>)>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct VariableDefinitions<'a> {
pub items: Vec<(Spanning<&'a str>, VariableDefinition<'a>)>,
pub struct VariableDefinitions<'a, S: fmt::Debug> {
pub items: Vec<(Spanning<&'a str>, VariableDefinition<'a, S>)>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct Field<'a> {
pub struct Field<'a, S: fmt::Debug> {
pub alias: Option<Spanning<&'a str>>,
pub name: Spanning<&'a str>,
pub arguments: Option<Spanning<Arguments<'a>>>,
pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Option<Vec<Selection<'a>>>,
pub arguments: Option<Spanning<Arguments<'a, S>>>,
pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
pub selection_set: Option<Vec<Selection<'a, S>>>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct FragmentSpread<'a> {
pub struct FragmentSpread<'a, S: fmt::Debug> {
pub name: Spanning<&'a str>,
pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct InlineFragment<'a> {
pub struct InlineFragment<'a, S: fmt::Debug> {
pub type_condition: Option<Spanning<&'a str>>,
pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Vec<Selection<'a>>,
pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
pub selection_set: Vec<Selection<'a, S>>,
}

/// Entry in a GraphQL selection set
Expand All @@ -104,16 +106,16 @@ pub struct InlineFragment<'a> {
/// ```
#[derive(Clone, PartialEq, Debug)]
#[allow(missing_docs)]
pub enum Selection<'a> {
Field(Spanning<Field<'a>>),
FragmentSpread(Spanning<FragmentSpread<'a>>),
InlineFragment(Spanning<InlineFragment<'a>>),
pub enum Selection<'a, S: fmt::Debug> {
Field(Spanning<Field<'a, S>>),
FragmentSpread(Spanning<FragmentSpread<'a, S>>),
InlineFragment(Spanning<InlineFragment<'a, S>>),
}

#[derive(Clone, PartialEq, Debug)]
pub struct Directive<'a> {
pub struct Directive<'a, S: fmt::Debug> {
pub name: Spanning<&'a str>,
pub arguments: Option<Spanning<Arguments<'a>>>,
pub arguments: Option<Spanning<Arguments<'a, S>>>,
}

#[derive(Clone, PartialEq, Debug)]
Expand All @@ -123,45 +125,45 @@ pub enum OperationType {
}

#[derive(Clone, PartialEq, Debug)]
pub struct Operation<'a> {
pub struct Operation<'a, S: fmt::Debug> {
pub operation_type: OperationType,
pub name: Option<Spanning<&'a str>>,
pub variable_definitions: Option<Spanning<VariableDefinitions<'a>>>,
pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Vec<Selection<'a>>,
pub variable_definitions: Option<Spanning<VariableDefinitions<'a, S>>>,
pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
pub selection_set: Vec<Selection<'a, S>>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct Fragment<'a> {
pub struct Fragment<'a, S: fmt::Debug> {
pub name: Spanning<&'a str>,
pub type_condition: Spanning<&'a str>,
pub directives: Option<Vec<Spanning<Directive<'a>>>>,
pub selection_set: Vec<Selection<'a>>,
pub directives: Option<Vec<Spanning<Directive<'a, S>>>>,
pub selection_set: Vec<Selection<'a, S>>,
}

#[derive(Clone, PartialEq, Debug)]
pub enum Definition<'a> {
Operation(Spanning<Operation<'a>>),
Fragment(Spanning<Fragment<'a>>),
pub enum Definition<'a, S: fmt::Debug> {
Operation(Spanning<Operation<'a, S>>),
Fragment(Spanning<Fragment<'a, S>>),
}

pub type Document<'a> = Vec<Definition<'a>>;
pub type Document<'a, S> = Vec<Definition<'a, S>>;

/// Parse an unstructured input value into a Rust data type.
///
/// The conversion _can_ fail, and must in that case return None. Implemented
/// automatically by the convenience macro `graphql_scalar!` or by deriving GraphQLEnum.
///
/// Must be implemented manually when manually exposing new enums or scalars.
pub trait FromInputValue: Sized {
pub trait FromInputValue<S: fmt::Debug>: Sized {
/// Performs the conversion.
fn from_input_value(v: &InputValue) -> Option<Self>;
fn from_input_value(v: &InputValue<S>) -> Option<Self>;
}

/// Losslessly clones a Rust data type into an InputValue.
pub trait ToInputValue: Sized {
pub trait ToInputValue<S: fmt::Debug>: Sized {
/// Performs the conversion.
fn to_input_value(&self) -> InputValue;
fn to_input_value(&self) -> InputValue<S>;
}

impl<'a> Type<'a> {
Expand Down Expand Up @@ -205,39 +207,49 @@ impl<'a> fmt::Display for Type<'a> {
}
}

impl InputValue {
impl<S> InputValue<S>
where
S: ScalarValue,
{
/// Construct a null value.
pub fn null() -> InputValue {
pub fn null() -> Self {
InputValue::Null
}

/// Construct an integer value.
pub fn int(i: i32) -> InputValue {
InputValue::Int(i)
pub fn int(i: i32) -> Self {
Self::scalar(i)
}

/// Construct a floating point value.
pub fn float(f: f64) -> InputValue {
InputValue::Float(f)
pub fn float(f: f64) -> Self {
Self::scalar(f)
}

/// Construct a boolean value.
pub fn boolean(b: bool) -> InputValue {
InputValue::Boolean(b)
pub fn boolean(b: bool) -> Self {
Self::scalar(b)
}

/// Construct a string value.
pub fn string<T: AsRef<str>>(s: T) -> InputValue {
pub fn string<T: AsRef<str>>(s: T) -> Self {
InputValue::String(s.as_ref().to_owned())
}

pub fn scalar<T>(v: T) -> Self
where
T: Into<S>,
{
InputValue::Scalar(v.into())
}

/// Construct an enum value.
pub fn enum_value<T: AsRef<str>>(s: T) -> InputValue {
pub fn enum_value<T: AsRef<str>>(s: T) -> Self {
InputValue::Enum(s.as_ref().to_owned())
}

/// Construct a variable value.
pub fn variable<T: AsRef<str>>(v: T) -> InputValue {
pub fn variable<T: AsRef<str>>(v: T) -> Self {
InputValue::Variable(v.as_ref().to_owned())
}

Expand All @@ -246,20 +258,20 @@ impl InputValue {
/// Convenience function to make each `InputValue` in the input vector
/// not contain any location information. Can be used from `ToInputValue`
/// implementations, where no source code position information is available.
pub fn list(l: Vec<InputValue>) -> InputValue {
pub fn list(l: Vec<Self>) -> Self {
InputValue::List(l.into_iter().map(Spanning::unlocated).collect())
}

/// Construct a located list.
pub fn parsed_list(l: Vec<Spanning<InputValue>>) -> InputValue {
pub fn parsed_list(l: Vec<Spanning<Self>>) -> Self {
InputValue::List(l)
}

/// Construct an unlocated object.
///
/// Similar to `InputValue::list`, it makes each key and value in the given
/// hash map not contain any location information.
pub fn object<K>(o: IndexMap<K, InputValue>) -> InputValue
pub fn object<K>(o: IndexMap<K, Self>) -> Self
where
K: AsRef<str> + Eq + Hash,
{
Expand All @@ -276,12 +288,12 @@ impl InputValue {
}

/// Construct a located object.
pub fn parsed_object(o: Vec<(Spanning<String>, Spanning<InputValue>)>) -> InputValue {
pub fn parsed_object(o: Vec<(Spanning<String>, Spanning<Self>)>) -> Self {
InputValue::Object(o)
}

/// Resolve all variables to their values.
pub fn into_const(self, vars: &Variables) -> InputValue {
pub fn into_const(self, vars: &Variables<S>) -> Self {
match self {
InputValue::Variable(v) => vars.get(&v).map_or_else(InputValue::null, Clone::clone),
InputValue::List(l) => InputValue::List(
Expand All @@ -301,9 +313,9 @@ impl InputValue {
/// Shorthand form of invoking `FromInputValue::from()`.
pub fn convert<T>(&self) -> Option<T>
where
T: FromInputValue,
T: FromInputValue<S>,
{
<T as FromInputValue>::from_input_value(self)
<T as FromInputValue<S>>::from_input_value(self)
}

/// Does the value represent null?
Expand Down Expand Up @@ -358,7 +370,7 @@ impl InputValue {
///
/// This constructs a new IndexMap that contain references to the keys
/// and values in `self`.
pub fn to_object_value(&self) -> Option<IndexMap<&str, &InputValue>> {
pub fn to_object_value(&self) -> Option<IndexMap<&str, &Self>> {
match *self {
InputValue::Object(ref o) => Some(
o.iter()
Expand All @@ -373,7 +385,7 @@ impl InputValue {
///
/// This constructs a new vector that contain references to the values
/// in `self`.
pub fn to_list_value(&self) -> Option<Vec<&InputValue>> {
pub fn to_list_value(&self) -> Option<Vec<&Self>> {
match *self {
InputValue::List(ref l) => Some(l.iter().map(|s| &s.item).collect()),
_ => None,
Expand All @@ -384,18 +396,20 @@ impl InputValue {
pub fn referenced_variables(&self) -> Vec<&str> {
match *self {
InputValue::Variable(ref name) => vec![name],
InputValue::List(ref l) => l.iter()
InputValue::List(ref l) => l
.iter()
.flat_map(|v| v.item.referenced_variables())
.collect(),
InputValue::Object(ref obj) => obj.iter()
InputValue::Object(ref obj) => obj
.iter()
.flat_map(|&(_, ref v)| v.item.referenced_variables())
.collect(),
_ => vec![],
}
}

/// Compare equality with another `InputValue` ignoring any source position information.
pub fn unlocated_eq(&self, other: &InputValue) -> bool {
pub fn unlocated_eq(&self, other: &Self) -> bool {
use InputValue::*;

match (self, other) {
Expand All @@ -406,7 +420,8 @@ impl InputValue {
| (&Enum(ref s1), &Enum(ref s2))
| (&Variable(ref s1), &Variable(ref s2)) => s1 == s2,
(&Boolean(b1), &Boolean(b2)) => b1 == b2,
(&List(ref l1), &List(ref l2)) => l1.iter()
(&List(ref l1), &List(ref l2)) => l1
.iter()
.zip(l2.iter())
.all(|(v1, v2)| v1.item.unlocated_eq(&v2.item)),
(&Object(ref o1), &Object(ref o2)) => {
Expand All @@ -421,7 +436,7 @@ impl InputValue {
}
}

impl fmt::Display for InputValue {
impl<S: fmt::Debug> fmt::Display for InputValue<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
InputValue::Null => write!(f, "null"),
Expand Down Expand Up @@ -460,24 +475,24 @@ impl fmt::Display for InputValue {
}
}

impl<'a> Arguments<'a> {
pub fn into_iter(self) -> vec::IntoIter<(Spanning<&'a str>, Spanning<InputValue>)> {
impl<'a, S: fmt::Debug> Arguments<'a, S> {
pub fn into_iter(self) -> vec::IntoIter<(Spanning<&'a str>, Spanning<InputValue<S>>)> {
self.items.into_iter()
}

pub fn iter(&self) -> slice::Iter<(Spanning<&'a str>, Spanning<InputValue>)> {
pub fn iter(&self) -> slice::Iter<(Spanning<&'a str>, Spanning<InputValue<S>>)> {
self.items.iter()
}

pub fn iter_mut(&mut self) -> slice::IterMut<(Spanning<&'a str>, Spanning<InputValue>)> {
pub fn iter_mut(&mut self) -> slice::IterMut<(Spanning<&'a str>, Spanning<InputValue<S>>)> {
self.items.iter_mut()
}

pub fn len(&self) -> usize {
self.items.len()
}

pub fn get(&self, key: &str) -> Option<&Spanning<InputValue>> {
pub fn get(&self, key: &str) -> Option<&Spanning<InputValue<S>>> {
self.items
.iter()
.filter(|&&(ref k, _)| k.item == key)
Expand All @@ -486,8 +501,8 @@ impl<'a> Arguments<'a> {
}
}

impl<'a> VariableDefinitions<'a> {
pub fn iter(&self) -> slice::Iter<(Spanning<&'a str>, VariableDefinition)> {
impl<'a, S: fmt::Debug> VariableDefinitions<'a, S> {
pub fn iter(&self) -> slice::Iter<(Spanning<&'a str>, VariableDefinition<S>)> {
self.items.iter()
}
}
Expand Down
Loading

0 comments on commit 21ed215

Please sign in to comment.