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 -- | The default name for the action actionName :: Meta.Name actionName = Meta.mkName "Action" -- | Converts a name to the equivalent titleized -- -- >> titleizeName $ mkName "action" -- Name "Action" titleizeName :: Meta.Name -> Meta.Name titleizeName name = Meta.nameBase name & capitalizeFirst & Meta.mkName where capitalizeFirst (c : cs) = toUpper c : cs capitalizeFirst other = other -- | Converts a function type into a list of types, skipping the arrows 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] -- | Creates a list of n elements from -- the sequence from a' to z' makePrimeVars :: Int -> [Meta.Pat] makePrimeVars n = ['a'..'z'] & fmap one & fmap (<> "'") & take n & makeVarsWith -- | Creates a list of n elements from -- the sequence from a to z 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)