module Elm.Ast
( ElmDefinition (..)
, ElmAlias (..)
, ElmType (..)
, ElmPrim (..)
, ElmRecordField (..)
, ElmConstructor (..)
, isEnum
, getConstructorNames
, TypeName (..)
, TypeRef (..)
, definitionToRef
) where
import Data.List.NonEmpty (NonEmpty, toList)
import Data.Text (Text)
data ElmDefinition
= DefAlias !ElmAlias
| DefType !ElmType
| DefPrim !ElmPrim
deriving (Show)
data ElmAlias = ElmAlias
{ elmAliasName :: !Text
, elmAliasFields :: !(NonEmpty ElmRecordField)
, elmAliasIsNewtype :: !Bool
} deriving (Show)
data ElmRecordField = ElmRecordField
{ elmRecordFieldType :: !TypeRef
, elmRecordFieldName :: !Text
} deriving (Show)
newtype TypeName = TypeName
{ unTypeName :: Text
} deriving (Show)
data ElmType = ElmType
{ elmTypeName :: !Text
, elmTypeVars :: ![Text]
, elmTypeIsNewtype :: !Bool
, elmTypeConstructors :: !(NonEmpty ElmConstructor)
} deriving (Show)
data ElmConstructor = ElmConstructor
{ elmConstructorName :: !Text
, elmConstructorFields :: ![TypeRef]
} deriving (Show)
isEnum :: ElmType -> Bool
isEnum ElmType{..} = null elmTypeVars && null (foldMap elmConstructorFields elmTypeConstructors)
getConstructorNames :: ElmType -> [Text]
getConstructorNames ElmType{..} = map elmConstructorName $ toList elmTypeConstructors
data ElmPrim
= ElmUnit
| ElmNever
| ElmBool
| ElmChar
| ElmInt
| ElmFloat
| ElmString
| ElmTime
| ElmMaybe !TypeRef
| ElmResult !TypeRef !TypeRef
| ElmPair !TypeRef !TypeRef
| ElmList !TypeRef
deriving (Show)
data TypeRef
= RefPrim !ElmPrim
| RefCustom !TypeName
deriving (Show)
definitionToRef :: ElmDefinition -> TypeRef
definitionToRef = \case
DefAlias ElmAlias{..} -> RefCustom $ TypeName elmAliasName
DefType ElmType{..} -> RefCustom $ TypeName elmTypeName
DefPrim elmPrim -> RefPrim elmPrim