morpheus-graphql-core-0.16.0: src/Data/Morpheus/Parsing/Internal/Value.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Morpheus.Parsing.Internal.Value
( enumValue,
parseDefaultValue,
Parse (..),
)
where
import Data.Morpheus.Parsing.Internal.Internal
( Parser,
)
import Data.Morpheus.Parsing.Internal.Terms
( brackets,
equal,
fieldNameColon,
ignoredTokens,
parseNegativeSign,
parseString,
parseTypeName,
setOf,
variable,
)
import Data.Morpheus.Types.Internal.AST
( CONST,
FieldName,
ObjectEntry (..),
OrdMap,
RAW,
ScalarValue (..),
Value (..),
decodeScientific,
)
import Relude
import Text.Megaparsec
( label,
sepBy,
)
import Text.Megaparsec.Byte
( string,
)
import Text.Megaparsec.Byte.Lexer (scientific)
valueNull :: Parser (Value a)
valueNull = string "null" $> Null
booleanValue :: Parser (Value a)
booleanValue = boolTrue <|> boolFalse
where
boolTrue = string "true" $> Scalar (Boolean True)
boolFalse = string "false" $> Scalar (Boolean False)
valueNumber :: Parser (Value a)
valueNumber =
Scalar . decodeScientific
<$> (signedNumber <$> parseNegativeSign <*> scientific)
where
signedNumber isNegative number
| isNegative = - number
| otherwise = number
enumValue :: Parser (Value a)
enumValue = Enum <$> parseTypeName <* ignoredTokens
stringValue :: Parser (Value a)
stringValue = label "stringValue" $ Scalar . String <$> parseString
listValue :: Parser a -> Parser [a]
listValue parser = label "list" $ brackets (parser `sepBy` ignoredTokens)
objectEntry :: Parser (Value a) -> Parser (ObjectEntry a)
objectEntry parser =
label "ObjectEntry" $
ObjectEntry <$> fieldNameColon <*> parser
objectValue :: Parser (Value a) -> Parser (OrdMap FieldName (ObjectEntry a))
objectValue = label "ObjectValue" . setOf . objectEntry
parsePrimitives :: Parser (Value a)
parsePrimitives =
valueNull <|> booleanValue <|> valueNumber <|> enumValue <|> stringValue
parseDefaultValue :: Parser (Value s)
parseDefaultValue = equal *> parseV
where
parseV :: Parser (Value s)
parseV = structValue parseV
class Parse a where
parse :: Parser a
instance Parse (Value RAW) where
parse = (VariableValue <$> variable) <|> structValue parse
instance Parse (Value CONST) where
parse = structValue parse
structValue :: Parser (Value a) -> Parser (Value a)
structValue parser =
label "Value" $
( parsePrimitives
<|> (Object <$> objectValue parser)
<|> (List <$> listValue parser)
)
<* ignoredTokens