{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Morpheus.Parsing.Request.Operation
( parseOperation
)
where
import Data.Functor ( ($>) )
import Data.Text ( Text )
import Text.Megaparsec ( label
, optional
, (<?>)
, (<|>)
)
import Text.Megaparsec.Char ( string )
import Data.Morpheus.Parsing.Internal.Internal
( Parser
, getLocation
)
import Data.Morpheus.Parsing.Internal.Pattern
( optionalDirectives )
import Data.Morpheus.Parsing.Internal.Terms
( operator
, parseMaybeTuple
, parseName
, parseType
, spaceAndComments1
, variable
)
import Data.Morpheus.Parsing.Internal.Value
( parseDefaultValue )
import Data.Morpheus.Parsing.Request.Selection
( parseSelectionSet )
import Data.Morpheus.Types.Internal.AST
( DefaultValue
, Operation(..)
, RawOperation
, Variable(..)
, OperationType(..)
, isNullable
)
variableDefinition :: Parser (Text, Variable DefaultValue)
variableDefinition = label "VariableDefinition" $ do
(name, variablePosition) <- variable
operator ':'
(variableTypeWrappers, variableType) <- parseType
defaultValue <- parseDefaultValue
pure
( name
, Variable { variableType
, isVariableRequired = not (isNullable variableTypeWrappers)
, variableTypeWrappers
, variablePosition
, variableValue = defaultValue
}
)
parseOperationDefinition :: Parser RawOperation
parseOperationDefinition = label "OperationDefinition" $ do
operationPosition <- getLocation
operationType <- parseOperationType
operationName <- optional parseName
operationArgs <- parseMaybeTuple variableDefinition
_directives <- optionalDirectives
operationSelection <- parseSelectionSet
pure
(Operation { operationName
, operationType
, operationArgs
, operationSelection
, operationPosition
}
)
parseOperationType :: Parser OperationType
parseOperationType = label "OperationType" $ do
kind <-
(string "query" $> Query)
<|> (string "mutation" $> Mutation)
<|> (string "subscription" $> Subscription)
spaceAndComments1
return kind
parseAnonymousQuery :: Parser RawOperation
parseAnonymousQuery = label "AnonymousQuery" $ do
operationPosition <- getLocation
operationSelection <- parseSelectionSet
pure
(Operation { operationName = Nothing
, operationType = Query
, operationArgs = []
, operationSelection
, operationPosition
}
)
<?> "can't parse AnonymousQuery"
parseOperation :: Parser RawOperation
parseOperation = parseAnonymousQuery <|> parseOperationDefinition