summaryrefslogtreecommitdiff
path: root/Data/GraphQL
diff options
context:
space:
mode:
authorTom Hunger <tehunger@gmail.com>2016-12-08 23:34:46 +0000
committerTom Hunger <tehunger@gmail.com>2016-12-09 00:03:20 +0000
commit87c92e9d6eed3cf7a45f9df8da45c3a5689d28e1 (patch)
treee29701fb022d8defc91b5b6e29e419455c6f479a /Data/GraphQL
parent61f0a06096cc05ebc008db7e4647390f9a066a44 (diff)
downloadgraphql-87c92e9d6eed3cf7a45f9df8da45c3a5689d28e1.tar.gz
Parse number as scientific and interpret meaning separately.
The current parser will fail parsing floats because it parses an int, and then stumbles on the dot. To fix I interpret the value with the scientific library which already is a dependency through attoparsec, so we're not introducing any extra downloads or compiling. I think this is still subtly wrong because "10.0" will be parsed as ValueInt, but because input argument ints are allowed to be coerced into doubles (according to the spec) this is probably acceptable.
Diffstat (limited to 'Data/GraphQL')
-rw-r--r--Data/GraphQL/Parser.hs16
1 files changed, 10 insertions, 6 deletions
diff --git a/Data/GraphQL/Parser.hs b/Data/GraphQL/Parser.hs
index 2de09b0..26902d4 100644
--- a/Data/GraphQL/Parser.hs
+++ b/Data/GraphQL/Parser.hs
@@ -8,14 +8,14 @@ import Control.Applicative ((<|>), empty, many, optional)
import Control.Monad (when)
import Data.Char (isDigit, isSpace)
import Data.Foldable (traverse_)
+import Data.Scientific (floatingOrInteger)
import Data.Text (Text, append)
import Data.Attoparsec.Text
( Parser
, (<?>)
, anyChar
- , decimal
- , double
+ , scientific
, endOfLine
, inClass
, many1
@@ -23,7 +23,6 @@ import Data.Attoparsec.Text
, option
, peekChar
, sepBy1
- , signed
, takeWhile
, takeWhile1
)
@@ -149,9 +148,7 @@ typeCondition = namedType
-- explicit types use the `typedValue` parser.
value :: Parser Value
value = ValueVariable <$> variable
- -- TODO: Handle maxBound, Int32 in spec.
- <|> ValueInt <$> tok (signed decimal)
- <|> ValueFloat <$> tok (signed double)
+ <|> number
<|> ValueBoolean <$> booleanValue
<|> ValueString <$> stringValue
-- `true` and `false` have been tried before
@@ -159,6 +156,13 @@ value = ValueVariable <$> variable
<|> ValueList <$> listValue
<|> ValueObject <$> objectValue
<?> "value error!"
+ where
+ number = do
+ v <- scientific
+ case floatingOrInteger v of
+ Left r -> pure (ValueFloat r)
+ -- TODO: Handle maxBound, Int32 in spec.
+ Right i -> pure (ValueInt i)
booleanValue :: Parser Bool
booleanValue = True <$ tok "true"