module Mu.GraphQL.Quasi.LostParser (
  -- * The Lost 'Parser'™️
  parseTypeSysDefinition
) where

import           Control.Applicative           ((<|>))
import           Data.Attoparsec.Text          (Parser, many1)
import qualified Data.Text                     as T
import           Language.GraphQL.Draft.Parser (nameParser, runParser, schemaDocument)
import qualified Language.GraphQL.Draft.Syntax as GQL
import           Text.Parser.Token             (braces, symbol, whiteSpace)

schemaDefinition :: Parser GQL.SchemaDefinition
schemaDefinition :: Parser SchemaDefinition
schemaDefinition = String -> Parser Text String
forall (m :: * -> *). TokenParsing m => String -> m String
symbol "schema" Parser Text String
-> Parser SchemaDefinition -> Parser SchemaDefinition
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser SchemaDefinition -> Parser SchemaDefinition
forall (m :: * -> *) a. TokenParsing m => m a -> m a
braces (
    Maybe [Directive]
-> [RootOperationTypeDefinition] -> SchemaDefinition
GQL.SchemaDefinition
      (Maybe [Directive]
 -> [RootOperationTypeDefinition] -> SchemaDefinition)
-> Parser Text (Maybe [Directive])
-> Parser Text ([RootOperationTypeDefinition] -> SchemaDefinition)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Directive] -> Parser Text (Maybe [Directive])
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe [Directive]
forall a. Maybe a
Nothing -- ignore [Directive]
      Parser Text ([RootOperationTypeDefinition] -> SchemaDefinition)
-> Parser Text [RootOperationTypeDefinition]
-> Parser SchemaDefinition
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text RootOperationTypeDefinition
-> Parser Text [RootOperationTypeDefinition]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many1 Parser Text RootOperationTypeDefinition
rootOperationParser
  )

rootOperationParser :: Parser GQL.RootOperationTypeDefinition
rootOperationParser :: Parser Text RootOperationTypeDefinition
rootOperationParser =
  OperationType -> NamedType -> RootOperationTypeDefinition
GQL.RootOperationTypeDefinition
    (OperationType -> NamedType -> RootOperationTypeDefinition)
-> Parser Text OperationType
-> Parser Text (NamedType -> RootOperationTypeDefinition)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Text OperationType
operationTypeParser Parser Text OperationType
-> Parser Text String -> Parser Text OperationType
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> Parser Text String
forall (m :: * -> *). TokenParsing m => String -> m String
symbol ":")
    Parser Text (NamedType -> RootOperationTypeDefinition)
-> Parser Text NamedType -> Parser Text RootOperationTypeDefinition
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Name -> NamedType
GQL.NamedType (Name -> NamedType) -> Parser Text Name -> Parser Text NamedType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text Name
nameParser)

operationTypeParser :: Parser GQL.OperationType
operationTypeParser :: Parser Text OperationType
operationTypeParser =
      OperationType
GQL.OperationTypeQuery OperationType -> Parser Text String -> Parser Text OperationType
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser Text String
forall (m :: * -> *). TokenParsing m => String -> m String
symbol "query"
  Parser Text OperationType
-> Parser Text OperationType -> Parser Text OperationType
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> OperationType
GQL.OperationTypeMutation OperationType -> Parser Text String -> Parser Text OperationType
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser Text String
forall (m :: * -> *). TokenParsing m => String -> m String
symbol "mutation"
  Parser Text OperationType
-> Parser Text OperationType -> Parser Text OperationType
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> OperationType
GQL.OperationTypeSubscription OperationType -> Parser Text String -> Parser Text OperationType
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser Text String
forall (m :: * -> *). TokenParsing m => String -> m String
symbol "subscription"

typeSystemDefinition :: Parser [GQL.TypeSystemDefinition]
typeSystemDefinition :: Parser [TypeSystemDefinition]
typeSystemDefinition = Parser Text ()
forall (m :: * -> *). TokenParsing m => m ()
whiteSpace Parser Text ()
-> Parser [TypeSystemDefinition] -> Parser [TypeSystemDefinition]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ([[TypeSystemDefinition]] -> [TypeSystemDefinition]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[TypeSystemDefinition]] -> [TypeSystemDefinition])
-> Parser Text [[TypeSystemDefinition]]
-> Parser [TypeSystemDefinition]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [TypeSystemDefinition]
-> Parser Text [[TypeSystemDefinition]]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many1 (
      (\(GQL.SchemaDocument d :: [TypeDefinition]
d) -> TypeDefinition -> TypeSystemDefinition
GQL.TypeSystemDefinitionType (TypeDefinition -> TypeSystemDefinition)
-> [TypeDefinition] -> [TypeSystemDefinition]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TypeDefinition]
d) (SchemaDocument -> [TypeSystemDefinition])
-> Parser Text SchemaDocument -> Parser [TypeSystemDefinition]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text SchemaDocument
schemaDocument
  Parser [TypeSystemDefinition]
-> Parser [TypeSystemDefinition] -> Parser [TypeSystemDefinition]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (TypeSystemDefinition
-> [TypeSystemDefinition] -> [TypeSystemDefinition]
forall a. a -> [a] -> [a]
: []) (TypeSystemDefinition -> [TypeSystemDefinition])
-> (SchemaDefinition -> TypeSystemDefinition)
-> SchemaDefinition
-> [TypeSystemDefinition]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SchemaDefinition -> TypeSystemDefinition
GQL.TypeSystemDefinitionSchema (SchemaDefinition -> [TypeSystemDefinition])
-> Parser SchemaDefinition -> Parser [TypeSystemDefinition]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser SchemaDefinition
schemaDefinition ))

parseTypeSysDefinition :: T.Text -> Either T.Text [GQL.TypeSystemDefinition]
parseTypeSysDefinition :: Text -> Either Text [TypeSystemDefinition]
parseTypeSysDefinition = Parser [TypeSystemDefinition]
-> Text -> Either Text [TypeSystemDefinition]
forall a. Parser a -> Text -> Either Text a
runParser Parser [TypeSystemDefinition]
typeSystemDefinition