module Data.Component.Mock.TH.Common
( actionName
, titleizeName
, functionTypeToList
, makePrimeVars
, makeVars
, Field(..)
, toField
, toVarExp
) where
import Relude
import Data.Char
import Language.Haskell.TH as Meta
import Language.Haskell.TH.Syntax as Meta
actionName :: Meta.Name
actionName = Meta.mkName "Action"
titleizeName :: Meta.Name -> Meta.Name
titleizeName name =
Meta.nameBase name
& capitalizeFirst
& Meta.mkName
where
capitalizeFirst (c : cs) = toUpper c : cs
capitalizeFirst other = other
functionTypeToList :: Meta.Type -> [Meta.Type]
functionTypeToList type' =
case type' of
Meta.AppT (Meta.AppT Meta.ArrowT t1) t2 ->
t1: functionTypeToList t2
Meta.SigT t _ ->
functionTypeToList t
Meta.ForallT _ _ t ->
functionTypeToList t
t ->
[t]
makePrimeVars :: Int -> [Meta.Pat]
makePrimeVars n =
['a'..'z']
& fmap one
& fmap (<> "'")
& take n
& makeVarsWith
makeVars :: Int -> [Meta.Pat]
makeVars n =
['a'..'z']
& fmap one
& take n
& makeVarsWith
data Field = Field
{ name :: Meta.Name
, argumentsLength :: Int
}
toField :: Meta.VarBangType -> Field
toField (fieldName, _, fieldType) = do
let functionTypes = functionTypeToList fieldType
Field
{ name = fieldName
, argumentsLength = length functionTypes - 1
}
toVarExp :: Meta.Pat -> Meta.Exp
toVarExp (Meta.VarP varName) =
Meta.VarE varName
toVarExp other =
error
$ "Mockazo: Error when running 'toVarExp' for value '" <> show other <> "'\n"
<> "Please file an issue for this at https://github.com/theam/mockazo/issues"
makeVarsWith :: [String] -> [Meta.Pat]
makeVarsWith varNames =
varNames
& fmap makeVar
where
makeVar varName =
Meta.VarP (Meta.mkName varName)