packages feed

hocon 0.1.0.1 → 0.1.0.2

raw patch · 5 files changed

+62/−22 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.HOCON: mapNode :: (Map String Config -> Config) -> Config -> Config
+ Text.Parser.HOCON.Internal: postProcessing :: Config -> Config

Files

hocon.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 479320fd325338bd94374a5beb7a949a9bb9804fc9b507fc863a1a4ad2f84b81+-- hash: 4bd9a308ad33bf13b1ecad16f71185175255207b4eb710c118d81821c614ae1f  name:           hocon-version:        0.1.0.1+version:        0.1.0.2 synopsis:       Small library for typesafe's configuration specification description:    Small library for typesafe's configuration specification category:       Data
src/Data/HOCON.hs view
@@ -7,7 +7,6 @@   , getList   , getBool   , isNull-  , mapNode   , getConfig   , pretty   )@@ -31,10 +30,6 @@ isNull :: Config -> Bool isNull HOCONNull = True isNull _         = False--mapNode :: (Map String Config -> Config) -> Config -> Config-mapNode f (HOCONNode nodes) = f nodes-mapNode _ conf              = conf  getNode :: String -> Config -> Maybe (Map String Config) getNode key conf = do
src/Text/Parser/HOCON/Internal.hs view
@@ -13,13 +13,14 @@   , nullParser   , preProcessing   , hoconParser+  , postProcessing   ) where  import Data.Bifunctor.Extra (mapValues)-import Data.HOCON (Config(..), mapNode)+import Data.HOCON (Config(..)) import Data.List.Split (splitOn)-import Data.Map (groupBy, sortByKey)+import Data.Map (groupBy, sortByKey, Map) import Data.String.Utils (replace, join, strip) import Text.ParserCombinators.Parsec   (char, Parser, alphaNum, digit, letter, noneOf, oneOf, space, string, between, sepBy, (<|>), many, many1, skipMany, try)@@ -81,7 +82,7 @@ booleanParser :: Parser Config booleanParser = do   whitespace-  bool <- string "true" <|> string "false"+  bool <- try (string "true" <|> string "false")   whitespace   return $ if bool == "true" then HOCONBool True else HOCONBool False @@ -110,23 +111,44 @@  preProcessing :: String -> String preProcessing =-  replace "\n" "," . replace "{\n" "{" . replace "\n}" "}" . replace ",\n" "," . join "\n" . map strip . splitOn "\n"+  replace "\n" ","+    . replace "[\n" "["+    . replace "\n]" "]"+    . replace "{\n" "{"+    . replace "\n}" "}"+    . replace ",\n" ","+    . join "\n"+    . map strip+    . splitOn "\n" +postProcessing :: Config -> Config+postProcessing (HOCONNode nodes) = HOCONNode . sort . removeDuplicates . group $ nodes++group :: Map String Config -> Map String Config+group nodes = do+  let grouped = groupBy fst nodes+  (key, configs) <- mapValues (map snd) grouped+  return (key, if all isNode configs then mergeAll configs else head configs)+ where+  isNode n = case n of+    HOCONNode _ -> True+    _           -> False++sort :: Map String Config -> Map String Config+sort = sortByKey+ hoconParser :: Parser Config-hoconParser = objectParser <|> do-  values <- sepBy parseProps (char ',')-  let grouped = groupAndMerge values-  let sorted = mapValues (mapNode (HOCONNode . sortByKey)) . sortByKey $ grouped-  return $ HOCONNode sorted+hoconParser = postProcessing <$> parser  where-  groupAndMerge values = do-    (key, mixedConfigsAndKeys) <- groupBy fst values-    let configs = map snd mixedConfigsAndKeys-    return (key, mergeAll configs)+  parser = objectParser <|> do+    values <- sepBy parseProps (char ',')+    return $ HOCONNode values +removeDuplicates :: Map String Config -> Map String Config+removeDuplicates = foldl (\acc e -> if any ((== fst e) . fst) acc then acc else e : acc) []+ mergeAll :: [Config] -> Config mergeAll = foldl1 merge  merge :: Config -> Config -> Config merge (HOCONNode a) (HOCONNode b) = HOCONNode (a ++ b)-
test/Text/Parser/HOCON/InternalSpec.hs view
@@ -5,7 +5,8 @@  import Data.HOCON (Config(..)) import Test.Hspec (describe, it, shouldBe, shouldSatisfy, Spec)-import Text.Parser.HOCON.Internal (arrayParser, numberParser, objectParser, parseProps, stringParser, hoconParser, preProcessing)+import Text.Parser.HOCON.Internal+  (arrayParser, numberParser, objectParser, parseProps, stringParser, hoconParser, preProcessing, postProcessing) import Text.ParserCombinators.Parsec (parse)  isLeft :: Either a b -> Bool@@ -60,6 +61,13 @@       preProcessing "{foo = bar\n}" `shouldBe` "{foo = bar}"       preProcessing "{foo = bar}" `shouldBe` "{foo = bar}"       preProcessing "{foo = bar\n  }" `shouldBe` "{foo = bar}"++  describe "postProcessing" $ it "groups all object with the same key, removes duplicates and sorts them" $ do+    postProcessing (HOCONNode [("foo", HOCONString "bar")]) `shouldBe` HOCONNode [("foo", HOCONString "bar")]+    postProcessing (HOCONNode [("foo", HOCONNode [("foo", HOCONString "bar")]), ("foo", HOCONNode [("bar", HOCONString "foo")])])+      `shouldBe` HOCONNode [("foo", HOCONNode [("bar", HOCONString "foo"), ("foo", HOCONString "bar")])]+    postProcessing (HOCONNode [("foo", HOCONString "bar"), ("foo", HOCONNumber 123)])+      `shouldBe` HOCONNode [("foo", HOCONNumber 123)]    describe "hoconParser" $ do     it "succeeds" $ do
test/Text/Parser/HOCONSpec.hs view
@@ -14,6 +14,21 @@     parseHOCON "foo = bar" `shouldBe` Right (HOCONNode [("foo", HOCONString "bar")])     parseHOCON "foo = bar\nbar = 123\nbaz = \"nani?!\""       `shouldBe` Right (HOCONNode [("bar", HOCONNumber 123), ("baz", HOCONString "nani?!"), ("foo", HOCONString "bar")])+    parseHOCON "{\n  \"foo\": \"bar\"\n}" `shouldBe` Right (HOCONNode [("foo", HOCONString "bar")])+    parseHOCON+        "foo = bar\nbar = true\nsomeObject {\n  someField = [\n    foo,\n    bar,\n    baz\n  ]\n  someOtherField = [\n    {\n      foo = bar\n    }\n  ]\n}"+      `shouldBe` Right+                   (HOCONNode+                     [ ("bar", HOCONBool True)+                     , ("foo", HOCONString "bar")+                     , ( "someObject"+                       , HOCONNode+                         [ ("someField"     , HOCONList [HOCONString "foo", HOCONString "bar", HOCONString "baz"])+                         , ("someOtherField", HOCONList [HOCONNode [("foo", HOCONString "bar")]])+                         ]+                       )+                     ]+                   )   it "fails" $ do     parseHOCON "foo = bar\n{\n  foo = bar\n}" `shouldSatisfy` isLeft     parseHOCON "{" `shouldSatisfy` isLeft