diff options
| author | Tom Hunger <tehunger@gmail.com> | 2016-12-08 23:34:46 +0000 |
|---|---|---|
| committer | Tom Hunger <tehunger@gmail.com> | 2016-12-09 00:03:20 +0000 |
| commit | 87c92e9d6eed3cf7a45f9df8da45c3a5689d28e1 (patch) | |
| tree | e29701fb022d8defc91b5b6e29e419455c6f479a /Data | |
| parent | 61f0a06096cc05ebc008db7e4647390f9a066a44 (diff) | |
| download | graphql-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')
| -rw-r--r-- | Data/GraphQL/Parser.hs | 16 |
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" |
