{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Faker.Provider.TH where
import Config
import Control.Monad.Catch
import Control.Monad.IO.Class
import Data.Char (toUpper)
import Data.Map.Strict (Map)
import Data.Monoid ((<>))
import Data.Text (Text, unpack)
import qualified Data.Text as T
import Data.Vector (Vector)
import Data.Yaml
import Faker
import Faker.Internal
import Language.Haskell.TH
textTitle :: Text -> Text
textTitle txt =
case T.uncons txt of
Nothing -> txt
Just (c, rem) -> T.cons (toUpper c) rem
genParser ::
Text
-> Text
-> Q [Dec]
genParser entityName fieldName = do
let funName =
mkName $
unpack $
"parse" <> (refinedText $ textTitle entityName) <>
(refinedText $ textTitle fieldName)
let parserFnName =
unpack $ "parse" <> (refinedText $ textTitle entityName) <> "Field"
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
let tvA = mkName "a"
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[AppT (ConT ''FromJSON) (VarT tvA), AppT (ConT ''Monoid) (VarT tvA)]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT
(AppT ArrowT (ConT ''Value))
(AppT (ConT ''Parser) (VarT tvA)))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE (VarE parserFn) (VarE tsettings))
(LitE (StringL (unpack fieldName)))))
[]
]
]
genParsers ::
Text
-> [Text]
-> Q [Dec]
genParsers entityName fieldName = do
let fieldNames = map textTitle fieldName
fieldNames' = refinedText $ T.concat fieldNames
funName =
mkName $
unpack $
"parse" <> (refinedText $ textTitle entityName) <> (fieldNames')
let parserFnName =
unpack $ "parse" <> (refinedText $ textTitle entityName) <> "Fields"
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
let tvA = mkName "a"
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[AppT (ConT ''FromJSON) (VarT tvA), AppT (ConT ''Monoid) (VarT tvA)]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT
(AppT ArrowT (ConT ''Value))
(AppT (ConT ''Parser) (VarT tvA)))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE (VarE parserFn) (VarE tsettings))
(ListE (map (\x -> LitE (StringL (unpack x))) fieldName))))
[]
]
]
genProviders ::
Text
-> [Text]
-> Q [Dec]
genProviders entityName fieldName = do
let fieldNames = map textTitle fieldName
fieldNames' = refinedText $ T.concat fieldNames
funName =
mkName $ unpack $ (refinedText entityName) <> fieldNames' <> "Provider"
tvM = mkName "m"
parserFnName =
unpack $ "parse" <> (refinedText $ textTitle entityName) <> fieldNames'
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[ AppT (ConT ''MonadThrow) (VarT tvM)
, AppT (ConT ''MonadIO) (VarT tvM)
]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT (VarT tvM) (AppT (ConT ''Vector) (ConT ''Text)))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE
(AppE (VarE 'fetchData) (VarE tsettings))
(ConE (mapSource entityName)))
(VarE parserFn)))
[]
]
]
genProvidersSingle ::
Text
-> [Text]
-> Q [Dec]
genProvidersSingle entityName fieldName = do
let fieldNames = map textTitle fieldName
fieldNames' = refinedText $ T.concat fieldNames
funName =
mkName $ unpack $ (refinedText entityName) <> fieldNames' <> "Provider"
tvM = mkName "m"
parserFnName =
unpack $ "parse" <> (refinedText $ textTitle entityName) <> fieldNames'
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[ AppT (ConT ''MonadThrow) (VarT tvM)
, AppT (ConT ''MonadIO) (VarT tvM)
]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT (VarT tvM) (AppT (ConT ''Vector) (ConT ''Text)))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE
(AppE (VarE 'fetchDataSingle) (VarE tsettings))
(ConE (mapSource entityName)))
(VarE parserFn)))
[]
]
]
genProvider ::
Text
-> Text
-> Q [Dec]
genProvider entityName fieldName = do
let funName =
mkName $
unpack $
(refinedText entityName) <> (refinedText $ textTitle fieldName) <>
"Provider"
tvM = mkName "m"
parserFnName =
unpack $
"parse" <> (refinedText $ textTitle entityName) <>
(refinedText $ textTitle fieldName)
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[ AppT (ConT ''MonadThrow) (VarT tvM)
, AppT (ConT ''MonadIO) (VarT tvM)
]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT (VarT tvM) (AppT (ConT ''Vector) (ConT ''Text)))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE
(AppE (VarE 'fetchData) (VarE tsettings))
(ConE (mapSource entityName)))
(VarE parserFn)))
[]
]
]
genParserUnresolved :: Text -> Text -> Q [Dec]
genParserUnresolved entityName fieldName = do
let funName =
mkName $
unpack $
"parse" <> (refinedText $ textTitle entityName) <>
(refinedText $ textTitle fieldName) <>
"Unresolved"
let parserFnName =
unpack $
"parseUnresolved" <> (refinedText $ textTitle entityName) <> "Field"
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
let tvA = mkName "a"
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[AppT (ConT ''FromJSON) (VarT tvA), AppT (ConT ''Monoid) (VarT tvA)]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT
(AppT ArrowT (ConT ''Value))
(AppT (ConT ''Parser) (AppT (ConT ''Unresolved) (VarT tvA))))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE (VarE parserFn) (VarE tsettings))
(LitE (StringL (unpack fieldName)))))
[]
]
]
genParserUnresolveds :: Text -> [Text] -> Q [Dec]
genParserUnresolveds entityName fieldNames = do
let fieldNames' = refinedText $ T.concat $ map textTitle fieldNames
funName =
mkName $
unpack $
"parse" <> (refinedText $ textTitle entityName) <> fieldNames' <>
"Unresolved"
let parserFnName =
unpack $
"parseUnresolved" <> (refinedText $ textTitle entityName) <> "Fields"
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
let tvA = mkName "a"
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[AppT (ConT ''FromJSON) (VarT tvA), AppT (ConT ''Monoid) (VarT tvA)]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT
(AppT ArrowT (ConT ''Value))
(AppT (ConT ''Parser) (AppT (ConT ''Unresolved) (VarT tvA))))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE (VarE parserFn) (VarE tsettings))
(ListE (map (\x -> LitE (StringL (unpack x))) fieldNames))))
[]
]
]
genProviderUnresolveds ::
Text
-> [Text]
-> Q [Dec]
genProviderUnresolveds entityName fieldNames = do
let fieldNames' = refinedText $ T.concat $ map textTitle fieldNames
entityName' = refinedText entityName
funName = mkName $ unpack $ entityName' <> fieldNames' <> "Provider"
tvM = mkName "m"
parserFnName =
unpack $
"parse" <> (textTitle entityName') <> fieldNames' <> "Unresolved"
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[ AppT (ConT ''MonadThrow) (VarT tvM)
, AppT (ConT ''MonadIO) (VarT tvM)
]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT
(VarT tvM)
(AppT (ConT ''Unresolved) (AppT (ConT ''Vector) (ConT ''Text))))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE
(AppE (VarE 'fetchData) (VarE tsettings))
(ConE (mapSource entityName)))
(VarE parserFn)))
[]
]
]
genProviderUnresolved ::
Text
-> Text
-> Q [Dec]
genProviderUnresolved entityName fieldName = do
let funName =
mkName $
unpack $ refinedText $ entityName <> (textTitle fieldName) <> "Provider"
tvM = mkName "m"
parserFnName =
unpack $
"parse" <> (refinedText $ textTitle entityName) <>
(refinedText $ textTitle fieldName) <>
"Unresolved"
parserName <- lookupValueName parserFnName
parserFn <-
case parserName of
Nothing -> fail $ "Faker.TH: Didn't find function " <> parserFnName
Just fn -> return fn
tsettings <- newName "settings"
return $
[ SigD
funName
(ForallT
[]
[ AppT (ConT ''MonadThrow) (VarT tvM)
, AppT (ConT ''MonadIO) (VarT tvM)
]
(AppT
(AppT ArrowT (ConT ''FakerSettings))
(AppT
(VarT tvM)
(AppT (ConT ''Unresolved) (AppT (ConT ''Vector) (ConT ''Text))))))
, FunD
funName
[ Clause
[VarP tsettings]
(NormalB
(AppE
(AppE
(AppE (VarE 'fetchData) (VarE tsettings))
(ConE (mapSource entityName)))
(VarE parserFn)))
[]
]
]
genAppParser :: Text -> Q [Dec]
genAppParser = genParser "app"
genAppProvider :: Text -> Q [Dec]
genAppProvider = genProvider "app"
genAppParserUnresolved :: Text -> Q [Dec]
genAppParserUnresolved = genParserUnresolved "app"
genAppProviderUnresolved :: Text -> Q [Dec]
genAppProviderUnresolved = genProviderUnresolved "app"