module Aws.Lambda.Meta.Dispatch
( generate
, decodeObj
, encodeObj
, Runtime.LambdaResult(..)
) where
import Data.Function ((&))
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Char as Char
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as LazyByteString
import qualified Language.Haskell.TH as Meta
import Aws.Lambda.Meta.Common
import qualified Aws.Lambda.Runtime.Common as Runtime
decodeObj :: FromJSON a => String -> a
decodeObj x =
case (eitherDecode $ LazyByteString.pack x) of
Left e -> error e
Right v -> v
encodeObj :: ToJSON a => a -> String
encodeObj x = LazyByteString.unpack (encode x)
generate :: [Text] -> Meta.ExpQ
generate handlerNames = do
caseExp <- expressionName "functionHandler"
matches <- traverse handlerCase handlerNames
unmatched <- unmatchedCase
pure $ Meta.CaseE caseExp (matches <> [unmatched])
handlerCase :: Text -> Meta.MatchQ
handlerCase lambdaHandler = do
let pat = Meta.LitP (Meta.StringL $ Text.unpack lambdaHandler)
body <- [e|do
result <- $(expressionName qualifiedName) (decodeObj $(expressionName "eventObject")) (decodeObj $(expressionName "contextObject"))
either (pure . Left . encodeObj) (pure . Right . $(constructorName "LambdaResult") . encodeObj) result |]
pure $ Meta.Match pat (Meta.NormalB body) []
where
qualifiedName =
lambdaHandler
& Text.splitOn "/"
& filter (Char.isUpper . Text.head)
& Text.intercalate "."
unmatchedCase :: Meta.MatchQ
unmatchedCase = do
let pattern = Meta.WildP
body <- [e|
pure $ Left ("Handler " <> $(expressionName "functionHandler") <> " does not exist on project")
|]
pure $ Meta.Match pattern (Meta.NormalB body) []