morpheus-graphql-0.11.0: src/Data/Morpheus/Parsing/Internal/Internal.hs
{-# LANGUAGE NamedFieldPuns #-}
module Data.Morpheus.Parsing.Internal.Internal
( Parser
, Position
, getLocation
, processParser
)
where
import qualified Data.List.NonEmpty as NonEmpty
import Data.Morpheus.Types.Internal.AST
( Position(..)
, GQLError(..)
, GQLErrors
)
import Data.Morpheus.Types.Internal.Resolving
( Eventless
, failure
, Result(..)
)
import Data.Text ( Text
, pack
)
import Text.Megaparsec ( ParseError
, ParseErrorBundle
( ParseErrorBundle
)
, ParsecT
, SourcePos
, attachSourcePos
, bundleErrors
, bundlePosState
, errorOffset
, getSourcePos
, parseErrorPretty
, runParserT
, SourcePos(..)
, unPos
)
import Data.Void (Void)
getLocation :: Parser Position
getLocation = fmap toLocation getSourcePos
toLocation :: SourcePos -> Position
toLocation SourcePos { sourceLine, sourceColumn } =
Position { line = unPos sourceLine, column = unPos sourceColumn }
type MyError = Void
type Parser = ParsecT MyError Text Eventless
type ErrorBundle = ParseErrorBundle Text MyError
processParser :: Parser a -> Text -> Eventless a
processParser parser txt = case runParserT parser [] txt of
Success { result } -> case result of
Right root -> pure root
Left parseError -> failure (processErrorBundle parseError)
Failure { errors } -> failure errors
processErrorBundle :: ErrorBundle -> GQLErrors
processErrorBundle = map parseErrorToGQLError . bundleToErrors
where
parseErrorToGQLError :: (ParseError Text MyError, SourcePos) -> GQLError
parseErrorToGQLError (err, position) = GQLError
{ message = pack (parseErrorPretty err)
, locations = [toLocation position]
}
bundleToErrors
:: ErrorBundle -> [(ParseError Text MyError, SourcePos)]
bundleToErrors ParseErrorBundle { bundleErrors, bundlePosState } =
NonEmpty.toList $ fst $ attachSourcePos errorOffset
bundleErrors
bundlePosState