language-conf 0.1.2.0 → 0.2.0.0
raw patch · 5 files changed
+102/−5 lines, 5 filesdep +aesondep +vector
Dependencies added: aeson, vector
Files
- language-conf.cabal +7/−1
- src/Data/Conf.hs +9/−3
- src/Data/Conf/Aeson.hs +8/−0
- src/Data/Conf/Types.hs +46/−1
- test/Data/Conf/AesonSpec.hs +32/−0
language-conf.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: language-conf-version: 0.1.2.0+version: 0.2.0.0 synopsis: Conf parsers and pretty-printers for the Haskell programming language. description: @language-conf@ contains @.conf@ (e.g. nginx configuration) parsers and pretty-printers for the Haskell programming language. "Data.Conf" exports all the API surface in the package.@@ -46,11 +46,14 @@ , semigroups >=0.18.1 , text >=1.2.2.1 , unordered-containers+ , vector+ , aeson exposed-modules: Data.Conf Data.Conf.PrettyPrint Data.Conf.Types Data.Conf.Internal+ Data.Conf.Aeson default-language: Haskell2010 executable conffmt@@ -67,6 +70,7 @@ buildable: False other-modules: Data.Conf+ Data.Conf.Aeson Data.Conf.Internal Data.Conf.PrettyPrint Data.Conf.Types@@ -89,8 +93,10 @@ , pretty , semigroups >=0.18.1 , text+ , aeson , transformers >=0.4.2.0 other-modules:+ Data.Conf.AesonSpec Data.ConfSpec SanitySpec default-language: Haskell2010
src/Data/Conf.hs view
@@ -17,7 +17,7 @@ , pPrintConf , runParser -- * Types- , Conf (..)+ , Conf , ConfStatement (..) , Block (..) , Comment (..)@@ -30,11 +30,17 @@ , argument -- * Pretty-printer , Pretty(..)- , pPrint+ -- * Aeson+ , fromToJSON+ , FromJSON(..)+ , ToJSON(..) ) where +import Data.Aeson+import Text.Megaparsec (runParser)++import Data.Conf.Aeson import Data.Conf.Internal import Data.Conf.PrettyPrint import Data.Conf.Types-import Text.Megaparsec (runParser)
+ src/Data/Conf/Aeson.hs view
@@ -0,0 +1,8 @@+module Data.Conf.Aeson+ where++import Data.Aeson+import Data.Conf.Types++fromToJSON :: ToJSON a => a -> Result Conf+fromToJSON = fromJSON . toJSON
src/Data/Conf/Types.hs view
@@ -1,7 +1,18 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeSynonymInstances #-} module Data.Conf.Types where -import Data.Text (Text)+import Control.Monad+import Data.Aeson+import Data.Aeson.Types+import qualified Data.HashMap.Strict as HashMap+import qualified Data.Scientific as Scientific+import Data.String+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Vector as Vector type Conf = [ConfStatement] @@ -21,3 +32,37 @@ data Expression = Expression Text [Text] deriving(Eq, Show)++instance FromJSON Conf where+ parseJSON (Object o) = do+ let oList = HashMap.toList o+ forM oList $ \(k, v) ->+ case v of+ o@(Object _) -> do+ cs <- parseJSON o+ return $ ConfStatementBlock (Block [k] cs)+ (Array vs) -> return $+ ConfStatementExpression (Expression k (map toExpressionValue (Vector.toList vs)))+ value -> return $+ ConfStatementExpression (Expression k [toExpressionValue value])+ where+ toExpressionValue (Number oc) =+ case Scientific.floatingOrInteger oc of+ Left f -> fromString (show (f :: Double))+ Right i -> fromString (show (i :: Integer))+ toExpressionValue (String oc) = oc+ toExpressionValue (Bool b) = if b then "true" else "false"++ parseJSON invalid = typeMismatch "Conf" invalid++instance ToJSON Conf where+ toJSON cs = object ps+ where+ ps = concatMap toPair cs+ toPair (ConfStatementExpression (Expression e [v])) = [ e .= String v ]+ toPair (ConfStatementExpression (Expression e vs)) = [ e .= toJSON vs ]+ toPair (ConfStatementBlock (Block [k] css)) = [ k .= toJSON css ]+ toPair (ConfStatementBlock (Block ks css)) = [ Text.pack (show ks) .= toJSON css ]+ toPair ConfStatementEmptyLine = []+ toPair (ConfStatementComment _) = []+
+ test/Data/Conf/AesonSpec.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE OverloadedStrings #-}+module Data.Conf.AesonSpec where++import Data.Aeson+import Data.Conf.Aeson+import Data.Conf.Types++import Test.Hspec++spec :: Spec+spec = do+ describe "fromValue" $+ it "should convert objects to ConfStatements" $ do+ let inp = object [ "hello" .= String "world"+ , "object" .= object [ "here" .= Number 8888+ ]+ ]+ fromJSON inp `shouldBe` Success [ ConfStatementExpression (Expression "hello" ["world"])+ , ConfStatementBlock (Block ["object"] [ ConfStatementExpression (Expression "here" ["8888"])+ ])+ ]++ describe "toValue" $+ it "should convert objects to ConfStatements" $ do+ let inp = [ ConfStatementExpression (Expression "hello" ["world"])+ , ConfStatementBlock (Block ["object"] [ ConfStatementExpression (Expression "here" ["8888"])+ ])+ ]+ toJSON inp `shouldBe` object [ "hello" .= String "world"+ , "object" .= object [ "here" .= String "8888"+ ]+ ]