module Hydra.Langs.Graphql.Language where

import Hydra.Kernel

import qualified Data.List as L
import qualified Data.Set as S


graphqlLanguage :: Language
graphqlLanguage :: Language
graphqlLanguage = LanguageName -> LanguageConstraints -> Language
Language (String -> LanguageName
LanguageName String
"hydra/langs/graphql") (LanguageConstraints -> Language)
-> LanguageConstraints -> Language
forall a b. (a -> b) -> a -> b
$ LanguageConstraints {
  -- Note: this language is for schemas and data only; support for queries may be added later
  languageConstraintsEliminationVariants :: Set EliminationVariant
languageConstraintsEliminationVariants = Set EliminationVariant
forall a. Set a
S.empty,
  languageConstraintsLiteralVariants :: Set LiteralVariant
languageConstraintsLiteralVariants = [LiteralVariant] -> Set LiteralVariant
forall a. Ord a => [a] -> Set a
S.fromList [
    LiteralVariant
LiteralVariantBoolean, -- Boolean
    LiteralVariant
LiteralVariantFloat,   -- Float
    LiteralVariant
LiteralVariantInteger, -- Int
    LiteralVariant
LiteralVariantString], -- String
  languageConstraintsFloatTypes :: Set FloatType
languageConstraintsFloatTypes = [FloatType] -> Set FloatType
forall a. Ord a => [a] -> Set a
S.fromList [
    FloatType
FloatTypeFloat64], -- Float
  languageConstraintsFunctionVariants :: Set FunctionVariant
languageConstraintsFunctionVariants = Set FunctionVariant
forall a. Set a
S.empty,
  languageConstraintsIntegerTypes :: Set IntegerType
languageConstraintsIntegerTypes = [IntegerType] -> Set IntegerType
forall a. Ord a => [a] -> Set a
S.fromList [
    IntegerType
IntegerTypeInt32], -- Int
  languageConstraintsTermVariants :: Set TermVariant
languageConstraintsTermVariants = [TermVariant] -> Set TermVariant
forall a. Ord a => [a] -> Set a
S.fromList [
    TermVariant
TermVariantList,
    TermVariant
TermVariantLiteral,
    TermVariant
TermVariantOptional,
    TermVariant
TermVariantRecord,
    TermVariant
TermVariantUnion], -- Unions are supported only in the form of enums
  languageConstraintsTypeVariants :: Set TypeVariant
languageConstraintsTypeVariants = [TypeVariant] -> Set TypeVariant
forall a. Ord a => [a] -> Set a
S.fromList [
    TypeVariant
TypeVariantList,
    TypeVariant
TypeVariantLiteral,
    TypeVariant
TypeVariantWrap,
    TypeVariant
TypeVariantOptional,
    TypeVariant
TypeVariantRecord,
    TypeVariant
TypeVariantUnion, -- Unions are supported only in the form of enums
    TypeVariant
TypeVariantVariable],
  languageConstraintsTypes :: Type -> Bool
languageConstraintsTypes = \Type
typ -> case Type -> Type
stripType Type
typ of
    -- If it is a union type, make sure it can be treated as an enum.
    TypeUnion RowType
rt -> (Bool -> FieldType -> Bool) -> Bool -> [FieldType] -> Bool
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl (\Bool
b FieldType
f -> Bool
b Bool -> Bool -> Bool
&& FieldType -> Bool
isEnumField FieldType
f) Bool
True ([FieldType] -> Bool) -> [FieldType] -> Bool
forall a b. (a -> b) -> a -> b
$ RowType -> [FieldType]
rowTypeFields RowType
rt
      where
        isUnitType :: Type -> Bool
isUnitType Type
t = case Type -> Type
stripType Type
t of
          TypeRecord (RowType Name
name Maybe Name
_ [FieldType]
fields) -> [FieldType] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
L.null [FieldType]
fields Bool -> Bool -> Bool
|| Name
name Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
_Unit
          Type
_ -> Bool
False
        isEnumField :: FieldType -> Bool
isEnumField = Type -> Bool
isUnitType (Type -> Bool) -> (FieldType -> Type) -> FieldType -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldType -> Type
fieldTypeType
    TypeOptional Type
et -> case Type -> Type
stripType Type
et of
      TypeOptional Type
_ -> Bool
False  -- No encoding for optionals within optionals
      Type
_ -> Bool
True
    Type
_ -> Bool
True}

graphqlReservedWords :: S.Set String
graphqlReservedWords :: Set String
graphqlReservedWords = [String] -> Set String
forall a. Ord a => [a] -> Set a
S.fromList [String
"true", String
"false"]