From d257d05d4e40dc8ca6fa45760c594a880ffcc2ec Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 12 Jan 2020 07:07:04 +0100 Subject: [PATCH] Parse enum and input object type definitions --- CHANGELOG.md | 2 +- src/Language/GraphQL/AST/Document.hs | 15 ++------ src/Language/GraphQL/AST/Parser.hs | 44 ++++++++++++++++++++---- tests/Language/GraphQL/AST/ParserSpec.hs | 28 +++++++++++++++ 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59b8105..21d2ef4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to ## [Unreleased] ### Added - AST for the GraphQL schema. -- Parser for the SchemaDefinition +- Parser for the SchemaDefinition and TypeDefinition. - `Trans.argument`. ### Changed diff --git a/src/Language/GraphQL/AST/Document.hs b/src/Language/GraphQL/AST/Document.hs index 74c6ce2..9b156b2 100644 --- a/src/Language/GraphQL/AST/Document.hs +++ b/src/Language/GraphQL/AST/Document.hs @@ -12,6 +12,7 @@ module Language.GraphQL.AST.Document , Description(..) , Directive(..) , Document + , EnumValueDefinition(..) , ExecutableDefinition(..) , FieldDefinition(..) , FragmentDefinition(..) @@ -289,7 +290,7 @@ data TypeDefinition | UnionTypeDefinition Description Name [Directive] (UnionMemberTypes []) | EnumTypeDefinition Description Name [Directive] [EnumValueDefinition] | InputObjectTypeDefinition - Description Name [Directive] InputFieldsDefinitionOpt + Description Name [Directive] [InputValueDefinition] deriving (Eq, Show) data TypeExtension @@ -310,7 +311,7 @@ data TypeExtension Name [Directive] (NonEmpty EnumValueDefinition) | EnumTypeDirectivesExtension Name (NonEmpty Directive) | InputObjectTypeInputFieldsDefinitionExtension - Name [Directive] InputFieldsDefinition + Name [Directive] (NonEmpty InputValueDefinition) | InputObjectTypeDirectivesExtension Name (NonEmpty Directive) deriving (Eq, Show) @@ -362,13 +363,3 @@ instance Foldable t => Show (UnionMemberTypes t) where data EnumValueDefinition = EnumValueDefinition Description Name [Directive] deriving (Eq, Show) - --- ** Input Objects - -newtype InputFieldsDefinition - = InputFieldsDefinition (NonEmpty InputValueDefinition) - deriving (Eq, Show) - -newtype InputFieldsDefinitionOpt - = InputFieldsDefinitionOpt [InputValueDefinition] - deriving (Eq, Show) diff --git a/src/Language/GraphQL/AST/Parser.hs b/src/Language/GraphQL/AST/Parser.hs index 41748b2..bb8a273 100644 --- a/src/Language/GraphQL/AST/Parser.hs +++ b/src/Language/GraphQL/AST/Parser.hs @@ -7,8 +7,8 @@ module Language.GraphQL.AST.Parser ) where import Control.Applicative (Alternative(..), optional) +import Control.Applicative.Combinators (sepBy1) import qualified Control.Applicative.Combinators.NonEmpty as NonEmpty -import Control.Applicative.Combinators (sepBy, sepBy1) import Data.Text (Text) import Language.GraphQL.AST.Document import Language.GraphQL.AST.Lexer @@ -40,6 +40,8 @@ typeDefinition = scalarTypeDefinition <|> objectTypeDefinition <|> interfaceTypeDefinition <|> unionTypeDefinition + <|> enumTypeDefinition + <|> inputObjectTypeDefinition "TypeDefinition" scalarTypeDefinition :: Parser TypeDefinition @@ -93,6 +95,35 @@ interfaceTypeDefinition = InterfaceTypeDefinition <*> braces (many fieldDefinition) "InterfaceTypeDefinition" +enumTypeDefinition :: Parser TypeDefinition +enumTypeDefinition = EnumTypeDefinition + <$> description + <* symbol "enum" + <*> name + <*> opt directives + <*> opt enumValuesDefinition + "EnumTypeDefinition" + where + enumValuesDefinition = braces (some enumValueDefinition) + +inputObjectTypeDefinition :: Parser TypeDefinition +inputObjectTypeDefinition = InputObjectTypeDefinition + <$> description + <* symbol "input" + <*> name + <*> opt directives + <*> opt inputFieldsDefinition + "InputObjectTypeDefinition" + where + inputFieldsDefinition = braces (some inputValueDefinition) + +enumValueDefinition :: Parser EnumValueDefinition +enumValueDefinition = EnumValueDefinition + <$> description + <*> enumValue + <*> opt directives + "EnumValueDefinition" + implementsInterfaces :: Foldable t => (Parser Text -> Parser Text -> Parser (t NamedType)) -> @@ -134,9 +165,8 @@ schemaDefinition = SchemaDefinition <*> opt directives <*> operationTypeDefinitions "SchemaDefinition" - -operationTypeDefinitions :: Parser OperationTypeDefinitions -operationTypeDefinitions = braces $ manyNE operationTypeDefinition + where + operationTypeDefinitions = braces $ NonEmpty.some operationTypeDefinition operationTypeDefinition :: Parser OperationTypeDefinition operationTypeDefinition = OperationTypeDefinition @@ -244,15 +274,15 @@ value = Variable <$> variable booleanValue = True <$ symbol "true" <|> False <$ symbol "false" - enumValue :: Parser Name - enumValue = but (symbol "true") *> but (symbol "false") *> but (symbol "null") *> name - listValue :: Parser [Value] listValue = brackets $ some value objectValue :: Parser [ObjectField] objectValue = braces $ some objectField +enumValue :: Parser Name +enumValue = but (symbol "true") *> but (symbol "false") *> but (symbol "null") *> name + objectField :: Parser ObjectField objectField = ObjectField <$> name <* colon <*> value diff --git a/tests/Language/GraphQL/AST/ParserSpec.hs b/tests/Language/GraphQL/AST/ParserSpec.hs index efb5b63..e561863 100644 --- a/tests/Language/GraphQL/AST/ParserSpec.hs +++ b/tests/Language/GraphQL/AST/ParserSpec.hs @@ -81,3 +81,31 @@ spec = describe "Parser" $ do name: String } |] + + it "parses minimal enum type definition" $ + parse document "" `shouldSucceedOn` [r| + enum Direction { + NORTH + EAST + SOUTH + WEST + } + |] + + it "parses minimal enum type definition" $ + parse document "" `shouldSucceedOn` [r| + enum Direction { + NORTH + EAST + SOUTH + WEST + } + |] + + it "parses minimal input object type definition" $ + parse document "" `shouldSucceedOn` [r| + input Point2D { + x: Float + y: Float + } + |]