From 1285c6dff8422b65b48b323f312ee06590060a79 Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Mon, 27 Nov 2023 10:45:39 +0530 Subject: [PATCH 1/7] Add Serde Support For AST --- Cargo.toml | 4 ++ src/position.rs | 3 +- src/query/ast.rs | 34 +++++++------ src/schema/ast.rs | 124 ++++++++++++++++++++++------------------------ 4 files changed, 84 insertions(+), 81 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 60365a2..7dc08f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,12 @@ version = "0.4.0" authors = ["Paul Colomiets "] edition = "2018" +[features] +serde = ["dep:serde"] + [dependencies] combine = "4.6.6" +serde = { version = "1.0.163", features = ["derive"], optional = true } thiserror = "1.0.11" [dev-dependencies] diff --git a/src/position.rs b/src/position.rs index a3aaf12..f854716 100644 --- a/src/position.rs +++ b/src/position.rs @@ -1,7 +1,8 @@ +use serde::Serialize; use std::fmt; /// Original position of element in source code -#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash)] +#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash, Serialize)] pub struct Pos { /// One-based line number pub line: usize, diff --git a/src/query/ast.rs b/src/query/ast.rs index af5be1d..a3b58d0 100644 --- a/src/query/ast.rs +++ b/src/query/ast.rs @@ -5,11 +5,13 @@ //! //! [graphql grammar]: http://facebook.github.io/graphql/October2016/#sec-Appendix-Grammar-Summary //! +use serde::Serialize; + +pub use crate::common::{Directive, Number, Text, Type, Value}; use crate::position::Pos; -pub use crate::common::{Directive, Number, Value, Text, Type}; /// Root of query data -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Document<'a, T: Text<'a>> { pub definitions: Vec>, } @@ -17,7 +19,7 @@ pub struct Document<'a, T: Text<'a>> { impl<'a> Document<'a, String> { pub fn into_static(self) -> Document<'static, String> { // To support both reference and owned values in the AST, - // all string data is represented with the ::common::Str<'a, T: Text<'a>> + // all string data is represented with the ::common::Str<'a, T: Text<'a>> // wrapper type. // This type must carry the lifetime of the query string, // and is stored in a PhantomData value on the Str type. @@ -33,13 +35,13 @@ impl<'a> Document<'a, String> { } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum Definition<'a, T: Text<'a>> { Operation(OperationDefinition<'a, T>), Fragment(FragmentDefinition<'a, T>), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct FragmentDefinition<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -48,7 +50,7 @@ pub struct FragmentDefinition<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum OperationDefinition<'a, T: Text<'a>> { SelectionSet(SelectionSet<'a, T>), Query(Query<'a, T>), @@ -56,7 +58,7 @@ pub enum OperationDefinition<'a, T: Text<'a>> { Subscription(Subscription<'a, T>), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Query<'a, T: Text<'a>> { pub position: Pos, pub name: Option, @@ -65,7 +67,7 @@ pub struct Query<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Mutation<'a, T: Text<'a>> { pub position: Pos, pub name: Option, @@ -74,7 +76,7 @@ pub struct Mutation<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Subscription<'a, T: Text<'a>> { pub position: Pos, pub name: Option, @@ -83,13 +85,13 @@ pub struct Subscription<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct SelectionSet<'a, T: Text<'a>> { pub span: (Pos, Pos), pub items: Vec>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct VariableDefinition<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -97,14 +99,14 @@ pub struct VariableDefinition<'a, T: Text<'a>> { pub default_value: Option>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum Selection<'a, T: Text<'a>> { Field(Field<'a, T>), FragmentSpread(FragmentSpread<'a, T>), InlineFragment(InlineFragment<'a, T>), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Field<'a, T: Text<'a>> { pub position: Pos, pub alias: Option, @@ -114,19 +116,19 @@ pub struct Field<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct FragmentSpread<'a, T: Text<'a>> { pub position: Pos, pub fragment_name: T::Value, pub directives: Vec>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum TypeCondition<'a, T: Text<'a>> { On(T::Value), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct InlineFragment<'a, T: Text<'a>> { pub position: Pos, pub type_condition: Option>, diff --git a/src/schema/ast.rs b/src/schema/ast.rs index b6ae6db..1c49245 100644 --- a/src/schema/ast.rs +++ b/src/schema/ast.rs @@ -1,13 +1,15 @@ use std::str::FromStr; +use serde::Serialize; use thiserror::Error; -pub use crate::common::{Directive, Type, Value, Text}; +pub use crate::common::{Directive, Text, Type, Value}; use crate::position::Pos; -#[derive(Debug, Clone, Default, PartialEq)] +#[derive(Debug, Clone, Default, PartialEq, Serialize)] pub struct Document<'a, T: Text<'a>> - where T: Text<'a> +where + T: Text<'a>, { pub definitions: Vec>, } @@ -31,8 +33,7 @@ impl<'a> Document<'a, String> { } } - -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum Definition<'a, T: Text<'a>> { SchemaDefinition(SchemaDefinition<'a, T>), TypeDefinition(TypeDefinition<'a, T>), @@ -40,7 +41,7 @@ pub enum Definition<'a, T: Text<'a>> { DirectiveDefinition(DirectiveDefinition<'a, T>), } -#[derive(Debug, Clone, Default, PartialEq)] +#[derive(Debug, Clone, Default, PartialEq, Serialize)] pub struct SchemaDefinition<'a, T: Text<'a>> { pub position: Pos, pub directives: Vec>, @@ -49,7 +50,7 @@ pub struct SchemaDefinition<'a, T: Text<'a>> { pub subscription: Option, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum TypeDefinition<'a, T: Text<'a>> { Scalar(ScalarType<'a, T>), Object(ObjectType<'a, T>), @@ -59,7 +60,7 @@ pub enum TypeDefinition<'a, T: Text<'a>> { InputObject(InputObjectType<'a, T>), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum TypeExtension<'a, T: Text<'a>> { Scalar(ScalarTypeExtension<'a, T>), Object(ObjectTypeExtension<'a, T>), @@ -69,7 +70,7 @@ pub enum TypeExtension<'a, T: Text<'a>> { InputObject(InputObjectTypeExtension<'a, T>), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct ScalarType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -78,7 +79,8 @@ pub struct ScalarType<'a, T: Text<'a>> { } impl<'a, T> ScalarType<'a, T> - where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -90,7 +92,7 @@ impl<'a, T> ScalarType<'a, T> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct ScalarTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -98,7 +100,8 @@ pub struct ScalarTypeExtension<'a, T: Text<'a>> { } impl<'a, T> ScalarTypeExtension<'a, T> - where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -109,7 +112,7 @@ impl<'a, T> ScalarTypeExtension<'a, T> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct ObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -120,7 +123,8 @@ pub struct ObjectType<'a, T: Text<'a>> { } impl<'a, T> ObjectType<'a, T> - where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -134,7 +138,7 @@ impl<'a, T> ObjectType<'a, T> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct ObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -144,7 +148,8 @@ pub struct ObjectTypeExtension<'a, T: Text<'a>> { } impl<'a, T> ObjectTypeExtension<'a, T> - where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -157,7 +162,7 @@ impl<'a, T> ObjectTypeExtension<'a, T> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct Field<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -167,7 +172,7 @@ pub struct Field<'a, T: Text<'a>> { pub directives: Vec>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct InputValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -177,7 +182,7 @@ pub struct InputValue<'a, T: Text<'a>> { pub directives: Vec>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct InterfaceType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -188,7 +193,8 @@ pub struct InterfaceType<'a, T: Text<'a>> { } impl<'a, T> InterfaceType<'a, T> - where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -202,7 +208,7 @@ impl<'a, T> InterfaceType<'a, T> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct InterfaceTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -212,7 +218,8 @@ pub struct InterfaceTypeExtension<'a, T: Text<'a>> { } impl<'a, T> InterfaceTypeExtension<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -225,7 +232,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct UnionType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -235,7 +242,8 @@ pub struct UnionType<'a, T: Text<'a>> { } impl<'a, T> UnionType<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -248,7 +256,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct UnionTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -257,7 +265,8 @@ pub struct UnionTypeExtension<'a, T: Text<'a>> { } impl<'a, T> UnionTypeExtension<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -269,7 +278,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct EnumType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -279,7 +288,8 @@ pub struct EnumType<'a, T: Text<'a>> { } impl<'a, T> EnumType<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -292,7 +302,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct EnumValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -301,7 +311,8 @@ pub struct EnumValue<'a, T: Text<'a>> { } impl<'a, T> EnumValue<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -313,7 +324,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct EnumTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -322,7 +333,8 @@ pub struct EnumTypeExtension<'a, T: Text<'a>> { } impl<'a, T> EnumTypeExtension<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -334,7 +346,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct InputObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -344,7 +356,8 @@ pub struct InputObjectType<'a, T: Text<'a>> { } impl<'a, T> InputObjectType<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -357,7 +370,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct InputObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -366,7 +379,8 @@ pub struct InputObjectTypeExtension<'a, T: Text<'a>> { } impl<'a, T> InputObjectTypeExtension<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -378,7 +392,7 @@ where T: Text<'a> } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] pub enum DirectiveLocation { // executable Query, @@ -404,7 +418,7 @@ pub enum DirectiveLocation { VariableDefinition, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub struct DirectiveDefinition<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -415,7 +429,8 @@ pub struct DirectiveDefinition<'a, T: Text<'a>> { } impl<'a, T> DirectiveDefinition<'a, T> -where T: Text<'a> +where + T: Text<'a>, { pub fn new(name: T::Value) -> Self { Self { @@ -460,28 +475,11 @@ impl DirectiveLocation { pub fn is_query(&self) -> bool { use self::DirectiveLocation::*; match *self { - Query - | Mutation - | Subscription - | Field - | FragmentDefinition - | FragmentSpread - | InlineFragment - => true, - - Schema - | Scalar - | Object - | FieldDefinition - | ArgumentDefinition - | Interface - | Union - | Enum - | EnumValue - | InputObject - | InputFieldDefinition - | VariableDefinition - => false, + Query | Mutation | Subscription | Field | FragmentDefinition | FragmentSpread + | InlineFragment => true, + + Schema | Scalar | Object | FieldDefinition | ArgumentDefinition | Interface | Union + | Enum | EnumValue | InputObject | InputFieldDefinition | VariableDefinition => false, } } @@ -495,11 +493,9 @@ impl DirectiveLocation { #[error("invalid directive location")] pub struct InvalidDirectiveLocation; - impl FromStr for DirectiveLocation { type Err = InvalidDirectiveLocation; - fn from_str(s: &str) -> Result - { + fn from_str(s: &str) -> Result { use self::DirectiveLocation::*; let val = match s { "QUERY" => Query, From 1067f99dd52400807cb905b34d0c606bae4d0806 Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Mon, 27 Nov 2023 11:16:10 +0530 Subject: [PATCH 2/7] Add Serde Support For AST --- .gitignore | 1 + Cargo.toml | 3 --- src/common.rs | 16 ++++++++++++++++ src/format.rs | 12 +++++++----- src/lib.rs | 15 ++++++++------- src/query/error.rs | 3 +-- src/query/mod.rs | 4 ++-- src/schema/error.rs | 3 +-- src/schema/mod.rs | 2 +- 9 files changed, 37 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 3a445b2..19430aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /Cargo.lock /.vagga /target +/.idea \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 7dc08f4..c545254 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,6 @@ version = "0.4.0" authors = ["Paul Colomiets "] edition = "2018" -[features] -serde = ["dep:serde"] - [dependencies] combine = "4.6.6" serde = { version = "1.0.163", features = ["derive"], optional = true } diff --git a/src/common.rs b/src/common.rs index 4deddac..551663a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -3,6 +3,8 @@ use std::{collections::BTreeMap, fmt}; use combine::easy::{Error, Info}; use combine::{choice, many, many1, optional, position, StdParseResult}; use combine::{parser, Parser}; +#[cfg(feature = "serde")] +use serde::Serialize; use crate::helpers::{ident, kind, name, punct}; use crate::position::Pos; @@ -11,6 +13,20 @@ use crate::tokenizer::{Kind as T, Token, TokenStream}; /// Text abstracts over types that hold a string value. /// It is used to make the AST generic over the string type. pub trait Text<'a>: 'a { + #[cfg(feature = "serde")] + type Value: 'a + + From<&'a str> + + AsRef + + std::borrow::Borrow + + PartialEq + + Eq + + PartialOrd + + Ord + + fmt::Debug + + Clone + + Serialize; + + #[cfg(not(feature = "serde"))] type Value: 'a + From<&'a str> + AsRef diff --git a/src/format.rs b/src/format.rs index 0983391..de24163 100644 --- a/src/format.rs +++ b/src/format.rs @@ -3,7 +3,6 @@ use std::default::Default; use crate::common::Directive; - #[derive(Debug, PartialEq)] pub(crate) struct Formatter<'a> { buf: String, @@ -171,13 +170,16 @@ impl<'a> Formatter<'a> { } fn dec_indent(&mut self) { - self.indent = self.indent.checked_sub(self.style.indent) + self.indent = self + .indent + .checked_sub(self.style.indent) .expect("negative indent"); } } -pub(crate) fn format_directives<'a, T>(dirs: &[Directive<'a, T>], f: &mut Formatter) - where T: crate::common::Text<'a>, +pub(crate) fn format_directives<'a, T>(dirs: &[Directive<'a, T>], f: &mut Formatter) +where + T: crate::common::Text<'a>, { for dir in dirs { f.write(" "); @@ -198,7 +200,7 @@ macro_rules! impl_display { ('a $($typ: ident, )+) => { $( - impl<'a, T> fmt::Display for $typ<'a, T> + impl<'a, T> fmt::Display for $typ<'a, T> where T: Text<'a>, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/lib.rs b/src/lib.rs index 01a767e..561cf66 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -91,20 +91,21 @@ //! #![warn(missing_debug_implementations)] -#[cfg(test)] #[macro_use] extern crate pretty_assertions; - +#[cfg(test)] +#[macro_use] +extern crate pretty_assertions; mod common; #[macro_use] mod format; -mod position; -mod tokenizer; mod helpers; +mod position; pub mod query; pub mod schema; +mod tokenizer; +pub use crate::format::Style; +pub use crate::position::Pos; +pub use crate::query::minify_query; pub use crate::query::parse_query; pub use crate::schema::parse_schema; -pub use crate::query::minify_query; -pub use crate::position::Pos; -pub use crate::format::Style; diff --git a/src/query/error.rs b/src/query/error.rs index 6907e55..4a6b662 100644 --- a/src/query/error.rs +++ b/src/query/error.rs @@ -1,12 +1,11 @@ use combine::easy::Errors; use thiserror::Error; -use crate::tokenizer::Token; use crate::position::Pos; +use crate::tokenizer::Token; pub type InternalError<'a> = Errors, Token<'a>, Pos>; - /// Error parsing query /// /// This structure is opaque for forward compatibility. We are exploring a diff --git a/src/query/mod.rs b/src/query/mod.rs index c5bbfb5..bff05e0 100644 --- a/src/query/mod.rs +++ b/src/query/mod.rs @@ -6,7 +6,7 @@ mod format; mod grammar; mod minify; -pub use self::grammar::{parse_query, consume_definition}; -pub use self::error::ParseError; pub use self::ast::*; +pub use self::error::ParseError; +pub use self::grammar::{consume_definition, parse_query}; pub use self::minify::minify_query; diff --git a/src/schema/error.rs b/src/schema/error.rs index 53ad541..3c19b57 100644 --- a/src/schema/error.rs +++ b/src/schema/error.rs @@ -1,12 +1,11 @@ use combine::easy::Errors; use thiserror::Error; -use crate::tokenizer::Token; use crate::position::Pos; +use crate::tokenizer::Token; pub type InternalError<'a> = Errors, Token<'a>, Pos>; - /// Error parsing schema /// /// This structure is opaque for forward compatibility. We are exploring a diff --git a/src/schema/mod.rs b/src/schema/mod.rs index 49d5e9d..80716d2 100644 --- a/src/schema/mod.rs +++ b/src/schema/mod.rs @@ -1,9 +1,9 @@ //! Schema definition language AST and utility //! mod ast; -mod grammar; mod error; mod format; +mod grammar; pub use self::ast::*; pub use self::error::ParseError; From 921f67ea42e71ff2ebe02cc95cbba2642898c190 Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Mon, 27 Nov 2023 11:21:05 +0530 Subject: [PATCH 3/7] Fix Build Issues --- src/common.rs | 4 +++ src/position.rs | 4 ++- src/query/ast.rs | 43 ++++++++++++++++++++---------- src/schema/ast.rs | 68 +++++++++++++++++++++++++++++++---------------- 4 files changed, 81 insertions(+), 38 deletions(-) diff --git a/src/common.rs b/src/common.rs index 551663a..9dcaf94 100644 --- a/src/common.rs +++ b/src/common.rs @@ -52,6 +52,7 @@ impl<'a> Text<'a> for std::borrow::Cow<'a, str> { } #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Directive<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -65,11 +66,13 @@ pub struct Directive<'a, T: Text<'a>> { /// in `serde_json`: encapsulate value in new-type, allowing type /// to be extended later. #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] // we use i64 as a reference implementation: graphql-js thinks even 32bit // integers is enough. We might consider lift this limit later though pub struct Number(pub(crate) i64); #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Value<'a, T: Text<'a>> { Variable(T::Value), Int(Number), @@ -103,6 +106,7 @@ impl<'a, T: Text<'a>> Value<'a, T> { } #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Type<'a, T: Text<'a>> { NamedType(T::Value), ListType(Box>), diff --git a/src/position.rs b/src/position.rs index f854716..7622679 100644 --- a/src/position.rs +++ b/src/position.rs @@ -1,8 +1,10 @@ +#[cfg(feature = "serde")] use serde::Serialize; use std::fmt; /// Original position of element in source code -#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash, Serialize)] +#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Pos { /// One-based line number pub line: usize, diff --git a/src/query/ast.rs b/src/query/ast.rs index a3b58d0..7b696e7 100644 --- a/src/query/ast.rs +++ b/src/query/ast.rs @@ -5,13 +5,15 @@ //! //! [graphql grammar]: http://facebook.github.io/graphql/October2016/#sec-Appendix-Grammar-Summary //! +#[cfg(feature = "serde")] use serde::Serialize; pub use crate::common::{Directive, Number, Text, Type, Value}; use crate::position::Pos; /// Root of query data -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Document<'a, T: Text<'a>> { pub definitions: Vec>, } @@ -35,13 +37,15 @@ impl<'a> Document<'a, String> { } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Definition<'a, T: Text<'a>> { Operation(OperationDefinition<'a, T>), Fragment(FragmentDefinition<'a, T>), } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct FragmentDefinition<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -50,7 +54,8 @@ pub struct FragmentDefinition<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum OperationDefinition<'a, T: Text<'a>> { SelectionSet(SelectionSet<'a, T>), Query(Query<'a, T>), @@ -58,7 +63,8 @@ pub enum OperationDefinition<'a, T: Text<'a>> { Subscription(Subscription<'a, T>), } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Query<'a, T: Text<'a>> { pub position: Pos, pub name: Option, @@ -67,7 +73,8 @@ pub struct Query<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Mutation<'a, T: Text<'a>> { pub position: Pos, pub name: Option, @@ -76,7 +83,8 @@ pub struct Mutation<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Subscription<'a, T: Text<'a>> { pub position: Pos, pub name: Option, @@ -85,13 +93,15 @@ pub struct Subscription<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct SelectionSet<'a, T: Text<'a>> { pub span: (Pos, Pos), pub items: Vec>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct VariableDefinition<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -99,14 +109,16 @@ pub struct VariableDefinition<'a, T: Text<'a>> { pub default_value: Option>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Selection<'a, T: Text<'a>> { Field(Field<'a, T>), FragmentSpread(FragmentSpread<'a, T>), InlineFragment(InlineFragment<'a, T>), } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Field<'a, T: Text<'a>> { pub position: Pos, pub alias: Option, @@ -116,19 +128,22 @@ pub struct Field<'a, T: Text<'a>> { pub selection_set: SelectionSet<'a, T>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct FragmentSpread<'a, T: Text<'a>> { pub position: Pos, pub fragment_name: T::Value, pub directives: Vec>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum TypeCondition<'a, T: Text<'a>> { On(T::Value), } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InlineFragment<'a, T: Text<'a>> { pub position: Pos, pub type_condition: Option>, diff --git a/src/schema/ast.rs b/src/schema/ast.rs index 1c49245..1ab9c0d 100644 --- a/src/schema/ast.rs +++ b/src/schema/ast.rs @@ -1,12 +1,13 @@ use std::str::FromStr; - +#[cfg(feature = "serde")] use serde::Serialize; use thiserror::Error; pub use crate::common::{Directive, Text, Type, Value}; use crate::position::Pos; -#[derive(Debug, Clone, Default, PartialEq, Serialize)] +#[derive(Debug, Clone, Default, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Document<'a, T: Text<'a>> where T: Text<'a>, @@ -33,7 +34,8 @@ impl<'a> Document<'a, String> { } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Definition<'a, T: Text<'a>> { SchemaDefinition(SchemaDefinition<'a, T>), TypeDefinition(TypeDefinition<'a, T>), @@ -41,7 +43,8 @@ pub enum Definition<'a, T: Text<'a>> { DirectiveDefinition(DirectiveDefinition<'a, T>), } -#[derive(Debug, Clone, Default, PartialEq, Serialize)] +#[derive(Debug, Clone, Default, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct SchemaDefinition<'a, T: Text<'a>> { pub position: Pos, pub directives: Vec>, @@ -50,7 +53,8 @@ pub struct SchemaDefinition<'a, T: Text<'a>> { pub subscription: Option, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum TypeDefinition<'a, T: Text<'a>> { Scalar(ScalarType<'a, T>), Object(ObjectType<'a, T>), @@ -60,7 +64,8 @@ pub enum TypeDefinition<'a, T: Text<'a>> { InputObject(InputObjectType<'a, T>), } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum TypeExtension<'a, T: Text<'a>> { Scalar(ScalarTypeExtension<'a, T>), Object(ObjectTypeExtension<'a, T>), @@ -70,7 +75,8 @@ pub enum TypeExtension<'a, T: Text<'a>> { InputObject(InputObjectTypeExtension<'a, T>), } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ScalarType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -92,7 +98,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ScalarTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -112,7 +119,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -138,7 +146,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -162,7 +171,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Field<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -172,7 +182,8 @@ pub struct Field<'a, T: Text<'a>> { pub directives: Vec>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InputValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -182,7 +193,8 @@ pub struct InputValue<'a, T: Text<'a>> { pub directives: Vec>, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InterfaceType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -208,7 +220,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InterfaceTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -232,7 +245,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct UnionType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -256,7 +270,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct UnionTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -278,7 +293,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct EnumType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -302,7 +318,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct EnumValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -324,7 +341,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct EnumTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -346,7 +364,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InputObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -370,7 +389,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InputObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -392,7 +412,8 @@ where } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum DirectiveLocation { // executable Query, @@ -418,7 +439,8 @@ pub enum DirectiveLocation { VariableDefinition, } -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct DirectiveDefinition<'a, T: Text<'a>> { pub position: Pos, pub description: Option, From 0a1900f01229b229909f8e8e7f899b684324d148 Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Thu, 7 Dec 2023 09:26:28 +0530 Subject: [PATCH 4/7] Support Serde Deserialization For AST --- src/schema/ast.rs | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/schema/ast.rs b/src/schema/ast.rs index 1ab9c0d..0f1d77f 100644 --- a/src/schema/ast.rs +++ b/src/schema/ast.rs @@ -1,13 +1,13 @@ use std::str::FromStr; #[cfg(feature = "serde")] -use serde::Serialize; +use serde::{Serialize, Deserialize}; use thiserror::Error; pub use crate::common::{Directive, Text, Type, Value}; use crate::position::Pos; #[derive(Debug, Clone, Default, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Document<'a, T: Text<'a>> where T: Text<'a>, @@ -35,7 +35,7 @@ impl<'a> Document<'a, String> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Definition<'a, T: Text<'a>> { SchemaDefinition(SchemaDefinition<'a, T>), TypeDefinition(TypeDefinition<'a, T>), @@ -44,7 +44,7 @@ pub enum Definition<'a, T: Text<'a>> { } #[derive(Debug, Clone, Default, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct SchemaDefinition<'a, T: Text<'a>> { pub position: Pos, pub directives: Vec>, @@ -54,7 +54,7 @@ pub struct SchemaDefinition<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TypeDefinition<'a, T: Text<'a>> { Scalar(ScalarType<'a, T>), Object(ObjectType<'a, T>), @@ -65,7 +65,7 @@ pub enum TypeDefinition<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TypeExtension<'a, T: Text<'a>> { Scalar(ScalarTypeExtension<'a, T>), Object(ObjectTypeExtension<'a, T>), @@ -76,7 +76,7 @@ pub enum TypeExtension<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ScalarType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -99,7 +99,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ScalarTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -120,7 +120,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -147,7 +147,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct ObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -172,7 +172,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Field<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -183,7 +183,7 @@ pub struct Field<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InputValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -194,7 +194,7 @@ pub struct InputValue<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InterfaceType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -221,7 +221,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InterfaceTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -246,7 +246,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct UnionType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -271,7 +271,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct UnionTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -294,7 +294,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct EnumType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -319,7 +319,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct EnumValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -342,7 +342,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct EnumTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -365,7 +365,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InputObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -390,7 +390,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct InputObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -413,7 +413,7 @@ where } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum DirectiveLocation { // executable Query, @@ -440,7 +440,7 @@ pub enum DirectiveLocation { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct DirectiveDefinition<'a, T: Text<'a>> { pub position: Pos, pub description: Option, From 0a1bb60d8d7cd52bbdf83d40cde2236d533ac4ec Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Thu, 7 Dec 2023 10:38:52 +0530 Subject: [PATCH 5/7] WIP: Fix Lifetime Issues For Support Serde Deserialization --- src/common.rs | 26 +++++++++++++++++--------- src/position.rs | 4 ++-- src/schema/ast.rs | 4 ++-- src/schema/format.rs | 4 +--- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/common.rs b/src/common.rs index 9dcaf94..674fe90 100644 --- a/src/common.rs +++ b/src/common.rs @@ -4,16 +4,19 @@ use combine::easy::{Error, Info}; use combine::{choice, many, many1, optional, position, StdParseResult}; use combine::{parser, Parser}; #[cfg(feature = "serde")] -use serde::Serialize; +use serde::{Deserialize, Serialize}; use crate::helpers::{ident, kind, name, punct}; use crate::position::Pos; use crate::tokenizer::{Kind as T, Token, TokenStream}; +#[cfg(feature = "serde")] /// Text abstracts over types that hold a string value. /// It is used to make the AST generic over the string type. -pub trait Text<'a>: 'a { - #[cfg(feature = "serde")] +pub trait Text<'a> +where + Self: 'a + Serialize + Deserialize<'a>, +{ type Value: 'a + From<&'a str> + AsRef @@ -24,9 +27,14 @@ pub trait Text<'a>: 'a { + Ord + fmt::Debug + Clone - + Serialize; + + Serialize + + Deserialize<'a>; +} - #[cfg(not(feature = "serde"))] +#[cfg(not(feature = "serde"))] +/// Text abstracts over types that hold a string value. +/// It is used to make the AST generic over the string type. +pub trait Text<'a>: 'a { type Value: 'a + From<&'a str> + AsRef @@ -52,7 +60,7 @@ impl<'a> Text<'a> for std::borrow::Cow<'a, str> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Directive<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -66,13 +74,13 @@ pub struct Directive<'a, T: Text<'a>> { /// in `serde_json`: encapsulate value in new-type, allowing type /// to be extended later. #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] // we use i64 as a reference implementation: graphql-js thinks even 32bit // integers is enough. We might consider lift this limit later though pub struct Number(pub(crate) i64); #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Value<'a, T: Text<'a>> { Variable(T::Value), Int(Number), @@ -106,7 +114,7 @@ impl<'a, T: Text<'a>> Value<'a, T> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Type<'a, T: Text<'a>> { NamedType(T::Value), ListType(Box>), diff --git a/src/position.rs b/src/position.rs index 7622679..8d77869 100644 --- a/src/position.rs +++ b/src/position.rs @@ -1,10 +1,10 @@ #[cfg(feature = "serde")] -use serde::Serialize; +use serde::{Deserialize, Serialize}; use std::fmt; /// Original position of element in source code #[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Pos { /// One-based line number pub line: usize, diff --git a/src/schema/ast.rs b/src/schema/ast.rs index 0f1d77f..9c53a80 100644 --- a/src/schema/ast.rs +++ b/src/schema/ast.rs @@ -1,6 +1,6 @@ -use std::str::FromStr; #[cfg(feature = "serde")] -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; +use std::str::FromStr; use thiserror::Error; pub use crate::common::{Directive, Text, Type, Value}; diff --git a/src/schema/format.rs b/src/schema/format.rs index 6ebc945..3efb7d8 100644 --- a/src/schema/format.rs +++ b/src/schema/format.rs @@ -1,9 +1,7 @@ -use std::fmt; - use crate::common::Text; use crate::format::{format_directives, Displayable, Formatter, Style}; - use crate::schema::ast::*; +use std::fmt; impl<'a, T> Document<'a, T> where From 6a660e06376e395156629f0d9992ae4995d38d24 Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Thu, 7 Dec 2023 13:39:34 +0530 Subject: [PATCH 6/7] Revert "WIP: Fix Lifetime Issues For Support Serde Deserialization" This reverts commit 0a1bb60d8d7cd52bbdf83d40cde2236d533ac4ec. --- src/common.rs | 26 +++++++++----------------- src/position.rs | 4 ++-- src/schema/ast.rs | 4 ++-- src/schema/format.rs | 4 +++- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/common.rs b/src/common.rs index 674fe90..9dcaf94 100644 --- a/src/common.rs +++ b/src/common.rs @@ -4,19 +4,16 @@ use combine::easy::{Error, Info}; use combine::{choice, many, many1, optional, position, StdParseResult}; use combine::{parser, Parser}; #[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +use serde::Serialize; use crate::helpers::{ident, kind, name, punct}; use crate::position::Pos; use crate::tokenizer::{Kind as T, Token, TokenStream}; -#[cfg(feature = "serde")] /// Text abstracts over types that hold a string value. /// It is used to make the AST generic over the string type. -pub trait Text<'a> -where - Self: 'a + Serialize + Deserialize<'a>, -{ +pub trait Text<'a>: 'a { + #[cfg(feature = "serde")] type Value: 'a + From<&'a str> + AsRef @@ -27,14 +24,9 @@ where + Ord + fmt::Debug + Clone - + Serialize - + Deserialize<'a>; -} + + Serialize; -#[cfg(not(feature = "serde"))] -/// Text abstracts over types that hold a string value. -/// It is used to make the AST generic over the string type. -pub trait Text<'a>: 'a { + #[cfg(not(feature = "serde"))] type Value: 'a + From<&'a str> + AsRef @@ -60,7 +52,7 @@ impl<'a> Text<'a> for std::borrow::Cow<'a, str> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Directive<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -74,13 +66,13 @@ pub struct Directive<'a, T: Text<'a>> { /// in `serde_json`: encapsulate value in new-type, allowing type /// to be extended later. #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] // we use i64 as a reference implementation: graphql-js thinks even 32bit // integers is enough. We might consider lift this limit later though pub struct Number(pub(crate) i64); #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Value<'a, T: Text<'a>> { Variable(T::Value), Int(Number), @@ -114,7 +106,7 @@ impl<'a, T: Text<'a>> Value<'a, T> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Type<'a, T: Text<'a>> { NamedType(T::Value), ListType(Box>), diff --git a/src/position.rs b/src/position.rs index 8d77869..7622679 100644 --- a/src/position.rs +++ b/src/position.rs @@ -1,10 +1,10 @@ #[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::fmt; /// Original position of element in source code #[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Default, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Pos { /// One-based line number pub line: usize, diff --git a/src/schema/ast.rs b/src/schema/ast.rs index 9c53a80..0f1d77f 100644 --- a/src/schema/ast.rs +++ b/src/schema/ast.rs @@ -1,6 +1,6 @@ -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; use std::str::FromStr; +#[cfg(feature = "serde")] +use serde::{Serialize, Deserialize}; use thiserror::Error; pub use crate::common::{Directive, Text, Type, Value}; diff --git a/src/schema/format.rs b/src/schema/format.rs index 3efb7d8..6ebc945 100644 --- a/src/schema/format.rs +++ b/src/schema/format.rs @@ -1,7 +1,9 @@ +use std::fmt; + use crate::common::Text; use crate::format::{format_directives, Displayable, Formatter, Style}; + use crate::schema::ast::*; -use std::fmt; impl<'a, T> Document<'a, T> where From 12a185856ae699f36cea27df5f2b927329853651 Mon Sep 17 00:00:00 2001 From: Anshul Sanghi Date: Thu, 7 Dec 2023 13:39:42 +0530 Subject: [PATCH 7/7] Revert "Support Serde Deserialization For AST" This reverts commit 0a1900f01229b229909f8e8e7f899b684324d148. --- src/schema/ast.rs | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/schema/ast.rs b/src/schema/ast.rs index 0f1d77f..1ab9c0d 100644 --- a/src/schema/ast.rs +++ b/src/schema/ast.rs @@ -1,13 +1,13 @@ use std::str::FromStr; #[cfg(feature = "serde")] -use serde::{Serialize, Deserialize}; +use serde::Serialize; use thiserror::Error; pub use crate::common::{Directive, Text, Type, Value}; use crate::position::Pos; #[derive(Debug, Clone, Default, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Document<'a, T: Text<'a>> where T: Text<'a>, @@ -35,7 +35,7 @@ impl<'a> Document<'a, String> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum Definition<'a, T: Text<'a>> { SchemaDefinition(SchemaDefinition<'a, T>), TypeDefinition(TypeDefinition<'a, T>), @@ -44,7 +44,7 @@ pub enum Definition<'a, T: Text<'a>> { } #[derive(Debug, Clone, Default, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct SchemaDefinition<'a, T: Text<'a>> { pub position: Pos, pub directives: Vec>, @@ -54,7 +54,7 @@ pub struct SchemaDefinition<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum TypeDefinition<'a, T: Text<'a>> { Scalar(ScalarType<'a, T>), Object(ObjectType<'a, T>), @@ -65,7 +65,7 @@ pub enum TypeDefinition<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum TypeExtension<'a, T: Text<'a>> { Scalar(ScalarTypeExtension<'a, T>), Object(ObjectTypeExtension<'a, T>), @@ -76,7 +76,7 @@ pub enum TypeExtension<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ScalarType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -99,7 +99,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ScalarTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -120,7 +120,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -147,7 +147,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct ObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -172,7 +172,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct Field<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -183,7 +183,7 @@ pub struct Field<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InputValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -194,7 +194,7 @@ pub struct InputValue<'a, T: Text<'a>> { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InterfaceType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -221,7 +221,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InterfaceTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -246,7 +246,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct UnionType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -271,7 +271,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct UnionTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -294,7 +294,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct EnumType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -319,7 +319,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct EnumValue<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -342,7 +342,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct EnumTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -365,7 +365,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InputObjectType<'a, T: Text<'a>> { pub position: Pos, pub description: Option, @@ -390,7 +390,7 @@ where } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct InputObjectTypeExtension<'a, T: Text<'a>> { pub position: Pos, pub name: T::Value, @@ -413,7 +413,7 @@ where } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub enum DirectiveLocation { // executable Query, @@ -440,7 +440,7 @@ pub enum DirectiveLocation { } #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize))] pub struct DirectiveDefinition<'a, T: Text<'a>> { pub position: Pos, pub description: Option,