forked from OSS/graphql
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.
This commit is contained in:
parent
61f0a06096
commit
87c92e9d6e
@ -8,14 +8,14 @@ import Control.Applicative ((<|>), empty, many, optional)
|
|||||||
import Control.Monad (when)
|
import Control.Monad (when)
|
||||||
import Data.Char (isDigit, isSpace)
|
import Data.Char (isDigit, isSpace)
|
||||||
import Data.Foldable (traverse_)
|
import Data.Foldable (traverse_)
|
||||||
|
import Data.Scientific (floatingOrInteger)
|
||||||
|
|
||||||
import Data.Text (Text, append)
|
import Data.Text (Text, append)
|
||||||
import Data.Attoparsec.Text
|
import Data.Attoparsec.Text
|
||||||
( Parser
|
( Parser
|
||||||
, (<?>)
|
, (<?>)
|
||||||
, anyChar
|
, anyChar
|
||||||
, decimal
|
, scientific
|
||||||
, double
|
|
||||||
, endOfLine
|
, endOfLine
|
||||||
, inClass
|
, inClass
|
||||||
, many1
|
, many1
|
||||||
@ -23,7 +23,6 @@ import Data.Attoparsec.Text
|
|||||||
, option
|
, option
|
||||||
, peekChar
|
, peekChar
|
||||||
, sepBy1
|
, sepBy1
|
||||||
, signed
|
|
||||||
, takeWhile
|
, takeWhile
|
||||||
, takeWhile1
|
, takeWhile1
|
||||||
)
|
)
|
||||||
@ -149,9 +148,7 @@ typeCondition = namedType
|
|||||||
-- explicit types use the `typedValue` parser.
|
-- explicit types use the `typedValue` parser.
|
||||||
value :: Parser Value
|
value :: Parser Value
|
||||||
value = ValueVariable <$> variable
|
value = ValueVariable <$> variable
|
||||||
-- TODO: Handle maxBound, Int32 in spec.
|
<|> number
|
||||||
<|> ValueInt <$> tok (signed decimal)
|
|
||||||
<|> ValueFloat <$> tok (signed double)
|
|
||||||
<|> ValueBoolean <$> booleanValue
|
<|> ValueBoolean <$> booleanValue
|
||||||
<|> ValueString <$> stringValue
|
<|> ValueString <$> stringValue
|
||||||
-- `true` and `false` have been tried before
|
-- `true` and `false` have been tried before
|
||||||
@ -159,6 +156,13 @@ value = ValueVariable <$> variable
|
|||||||
<|> ValueList <$> listValue
|
<|> ValueList <$> listValue
|
||||||
<|> ValueObject <$> objectValue
|
<|> ValueObject <$> objectValue
|
||||||
<?> "value error!"
|
<?> "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 :: Parser Bool
|
||||||
booleanValue = True <$ tok "true"
|
booleanValue = True <$ tok "true"
|
||||||
|
@ -34,7 +34,8 @@ library
|
|||||||
attoparsec >= 0.10.4.0,
|
attoparsec >= 0.10.4.0,
|
||||||
base >= 4.7 && < 5,
|
base >= 4.7 && < 5,
|
||||||
text >= 0.11.3.1,
|
text >= 0.11.3.1,
|
||||||
unordered-containers >= 0.2.5.0
|
unordered-containers >= 0.2.5.0,
|
||||||
|
scientific >=0.3.1 && <0.4
|
||||||
if impl(ghc >= 8.0)
|
if impl(ghc >= 8.0)
|
||||||
ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances
|
ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user