module Stratosphere.Helpers
( maybeField
, prefixNamer
, prefixFieldRules
, modTemplateJSONField
, NamedItem (..)
, namedItemToJSON
, namedItemFromJSON
) where
import Control.Lens (set)
import Control.Lens.TH
import Data.Aeson
import Data.Aeson.Types (Parser)
import Data.Char (isUpper, toLower)
import qualified Data.HashMap.Strict as HM
import Data.List (stripPrefix)
import Data.Maybe (maybeToList)
import qualified Data.Text as T
import Language.Haskell.TH
maybeField :: ToJSON a => T.Text -> Maybe a -> Maybe (T.Text, Value)
maybeField field = fmap ((field .=) . toJSON)
prefixNamer :: String -> Name -> [Name] -> Name -> [DefName]
prefixNamer prefix _ _ field = maybeToList $
do
fieldPart <- stripPrefix prefix (nameBase field)
method <- computeMethod fieldPart
let cls = "Has" ++ fieldPart
return (MethodName (mkName cls) (mkName method))
where computeMethod (x:xs) | isUpper x = Just (toLower x : xs)
computeMethod _ = Nothing
prefixFieldRules :: String -> LensRules
prefixFieldRules prefix = set lensField (prefixNamer prefix) defaultFieldRules
modTemplateJSONField :: String -> String
modTemplateJSONField "templateFormatVersion" = "AWSTemplateFormatVersion"
modTemplateJSONField s = drop 8 s
class NamedItem a where
itemName :: a -> T.Text
nameToJSON :: a -> Value
nameParseJSON :: T.Text -> Object -> Parser a
namedItemToJSON :: (NamedItem a) => [a] -> Value
namedItemToJSON xs =
object $ fmap (\x -> itemName x .= nameToJSON x) xs
namedItemFromJSON :: (NamedItem a) => Value -> Parser [a]
namedItemFromJSON v = do
objs <- parseJSON v :: Parser (HM.HashMap T.Text Value)
sequence [withObject "NamedItem" (nameParseJSON n) obj |
(n, obj) <- HM.toList objs]