From d7bf7a12151b2c6e9ced8dddc7a303bd0e6e20a9 Mon Sep 17 00:00:00 2001 From: Michael Snoyman Date: Wed, 19 Nov 2014 21:08:43 +0200 Subject: [PATCH] Yesod.Default.Config2 --- yesod/ChangeLog.md | 3 ++ yesod/Yesod/Default/Config2.hs | 68 ++++++++++++++++++++++++++++++++++ yesod/yesod.cabal | 3 +- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 yesod/ChangeLog.md create mode 100644 yesod/Yesod/Default/Config2.hs diff --git a/yesod/ChangeLog.md b/yesod/ChangeLog.md new file mode 100644 index 00000000..39d09923 --- /dev/null +++ b/yesod/ChangeLog.md @@ -0,0 +1,3 @@ +## 1.4.1 + +Provide the `Yesod.Default.Config2` module, for use by newer scaffoldings. diff --git a/yesod/Yesod/Default/Config2.hs b/yesod/Yesod/Default/Config2.hs new file mode 100644 index 00000000..f11e7e34 --- /dev/null +++ b/yesod/Yesod/Default/Config2.hs @@ -0,0 +1,68 @@ +{-# LANGUAGE OverloadedStrings #-} +-- | Some next-gen helper functions for the scaffolding's configuration system. +module Yesod.Default.Config2 + ( MergedValue (..) + , applyCurrentEnv + , getCurrentEnv + , applyEnv + ) where + +import Data.Monoid +import Data.Aeson +import qualified Data.HashMap.Strict as H +import Data.Text (Text, pack) +import System.Environment (getEnvironment) +import Control.Arrow ((***)) +import Control.Applicative ((<$>)) +import Control.Monad (guard) +import Data.Text.Encoding (encodeUtf8) +import qualified Data.Yaml as Y + +newtype MergedValue = MergedValue { getMergedValue :: Value } + +instance Monoid MergedValue where + mempty = MergedValue $ Object H.empty + MergedValue x `mappend` MergedValue y = MergedValue $ mergeValues x y + +-- | Left biased +mergeValues :: Value -> Value -> Value +mergeValues (Object x) (Object y) = Object $ H.unionWith mergeValues x y +mergeValues (Object x) y | H.null x = y +mergeValues x _ = x + +applyEnv :: H.HashMap Text Text -> Value -> Value +applyEnv env = + goV + where + goV (Object o) = + case checkEnv o of + Just (name, value) -> + case H.lookup name env of + Nothing -> value + Just t -> matchType value t + Nothing -> Object $ goV <$> o + goV (Array a) = Array (goV <$> a) + goV v = v + + checkEnv o = do + guard $ H.size o == 2 + String name <- H.lookup "env" o + value <- H.lookup "value" o + return (name, value) + +matchType :: Value -> Text -> Value +matchType (Number _) t = tryWrap Number t +matchType (Bool _) t = tryWrap Bool t +matchType _ t = String t + +tryWrap :: FromJSON a => (a -> Value) -> Text -> Value +tryWrap con t = + case Y.decode $ encodeUtf8 t of + Nothing -> String t + Just x -> con x + +getCurrentEnv :: IO (H.HashMap Text Text) +getCurrentEnv = fmap (H.fromList . map (pack *** pack)) getEnvironment + +applyCurrentEnv :: Value -> IO Value +applyCurrentEnv orig = flip applyEnv orig <$> getCurrentEnv diff --git a/yesod/yesod.cabal b/yesod/yesod.cabal index b3383d54..0467f10e 100644 --- a/yesod/yesod.cabal +++ b/yesod/yesod.cabal @@ -1,5 +1,5 @@ name: yesod -version: 1.4.0 +version: 1.4.1 license: MIT license-file: LICENSE author: Michael Snoyman @@ -50,6 +50,7 @@ library exposed-modules: Yesod , Yesod.Default.Config + , Yesod.Default.Config2 , Yesod.Default.Main , Yesod.Default.Util , Yesod.Default.Handlers