Add VariableValue Aeson instance
This commit is contained in:
parent
79ed58fa67
commit
dc813621fd
@ -32,7 +32,10 @@ library
|
|||||||
build-depends:
|
build-depends:
|
||||||
aeson ^>= 2.0.3,
|
aeson ^>= 2.0.3,
|
||||||
base ^>=4.14.3.0,
|
base ^>=4.14.3.0,
|
||||||
graphql ^>= 1.0.2
|
graphql ^>= 1.0.2,
|
||||||
|
scientific ^>= 0.3.7,
|
||||||
|
text ^>= 1.2.5,
|
||||||
|
unordered-containers ^>= 0.2.16
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
test-suite graphql-test
|
test-suite graphql-test
|
||||||
|
@ -6,8 +6,15 @@ module Language.GraphQL.Serialize
|
|||||||
|
|
||||||
import qualified Data.Aeson as Aeson
|
import qualified Data.Aeson as Aeson
|
||||||
import qualified Data.Aeson.Key as Aeson.Key
|
import qualified Data.Aeson.Key as Aeson.Key
|
||||||
|
import qualified Data.Aeson.KeyMap as KeyMap
|
||||||
|
import Data.HashMap.Strict (HashMap)
|
||||||
|
import qualified Data.HashMap.Strict as HashMap
|
||||||
|
import Data.Scientific (toBoundedInteger, toRealFloat)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Language.GraphQL.AST (Name)
|
||||||
import Language.GraphQL.Execute.Coerce
|
import Language.GraphQL.Execute.Coerce
|
||||||
import qualified Language.GraphQL.Execute.OrderedMap as OrderedMap
|
import qualified Language.GraphQL.Execute.OrderedMap as OrderedMap
|
||||||
|
import qualified Language.GraphQL.Type.In as In
|
||||||
import qualified Language.GraphQL.Type.Out as Out
|
import qualified Language.GraphQL.Type.Out as Out
|
||||||
import qualified Language.GraphQL.Type as Type
|
import qualified Language.GraphQL.Type as Type
|
||||||
|
|
||||||
@ -41,3 +48,54 @@ instance Serialize JSON where
|
|||||||
toJSONKeyValue (key, value) = (Aeson.Key.fromText key, Aeson.toJSON value)
|
toJSONKeyValue (key, value) = (Aeson.Key.fromText key, Aeson.toJSON value)
|
||||||
serialize _ _ = Nothing
|
serialize _ _ = Nothing
|
||||||
null = JSON Aeson.Null
|
null = JSON Aeson.Null
|
||||||
|
|
||||||
|
instance VariableValue Aeson.Value where
|
||||||
|
coerceVariableValue _ Aeson.Null = Just Type.Null
|
||||||
|
coerceVariableValue (In.ScalarBaseType scalarType) value
|
||||||
|
| (Aeson.String stringValue) <- value = Just $ Type.String stringValue
|
||||||
|
| (Aeson.Bool booleanValue) <- value = Just $ Type.Boolean booleanValue
|
||||||
|
| (Aeson.Number numberValue) <- value
|
||||||
|
, (Type.ScalarType "Float" _) <- scalarType =
|
||||||
|
Just $ Type.Float $ toRealFloat numberValue
|
||||||
|
| (Aeson.Number numberValue) <- value = -- ID or Int
|
||||||
|
Type.Int <$> toBoundedInteger numberValue
|
||||||
|
coerceVariableValue (In.EnumBaseType _) (Aeson.String stringValue) =
|
||||||
|
Just $ Type.Enum stringValue
|
||||||
|
coerceVariableValue (In.InputObjectBaseType objectType) value
|
||||||
|
| (Aeson.Object objectValue) <- value = do
|
||||||
|
let (In.InputObjectType _ _ inputFields) = objectType
|
||||||
|
(newObjectValue, resultMap) <- foldWithKey objectValue inputFields
|
||||||
|
if KeyMap.null newObjectValue
|
||||||
|
then Just $ Type.Object resultMap
|
||||||
|
else Nothing
|
||||||
|
where
|
||||||
|
foldWithKey :: Aeson.Object
|
||||||
|
-> HashMap Name In.InputField
|
||||||
|
-> Maybe (Aeson.Object, HashMap Name Type.Value)
|
||||||
|
foldWithKey objectValue = HashMap.foldrWithKey matchFieldValues'
|
||||||
|
$ Just (objectValue, HashMap.empty)
|
||||||
|
matchFieldValues' :: Text
|
||||||
|
-> In.InputField
|
||||||
|
-> Maybe (Aeson.Object, HashMap Name Type.Value)
|
||||||
|
-> Maybe (Aeson.Object, HashMap Name Type.Value)
|
||||||
|
matchFieldValues' _ _ Nothing = Nothing
|
||||||
|
matchFieldValues' fieldName inputField (Just (objectValue, resultMap)) =
|
||||||
|
let fieldKey = Aeson.Key.fromText fieldName
|
||||||
|
In.InputField _ fieldType _ = inputField
|
||||||
|
insert = flip (HashMap.insert fieldName) resultMap
|
||||||
|
newObjectValue = KeyMap.delete fieldKey objectValue
|
||||||
|
in case KeyMap.lookup fieldKey objectValue of
|
||||||
|
Just variableValue -> do
|
||||||
|
coerced <- coerceVariableValue fieldType variableValue
|
||||||
|
pure (newObjectValue, insert coerced)
|
||||||
|
Nothing -> Just (objectValue, resultMap)
|
||||||
|
coerceVariableValue (In.ListBaseType listType) value
|
||||||
|
| (Aeson.Array arrayValue) <- value =
|
||||||
|
Type.List <$> foldr foldVector (Just []) arrayValue
|
||||||
|
| otherwise = coerceVariableValue listType value
|
||||||
|
where
|
||||||
|
foldVector _ Nothing = Nothing
|
||||||
|
foldVector variableValue (Just list) = do
|
||||||
|
coerced <- coerceVariableValue listType variableValue
|
||||||
|
pure $ coerced : list
|
||||||
|
coerceVariableValue _ _ = Nothing
|
||||||
|
Loading…
Reference in New Issue
Block a user