packages feed

aeson-flatten (empty) → 0.1.0.0

raw patch · 6 files changed

+174/−0 lines, 6 filesdep +aesondep +aeson-flattendep +basesetup-changed

Dependencies added: aeson, aeson-flatten, base, bytestring, hspec, text, unordered-containers

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,17 @@+# aeson-prefix++JSON flatten for [Aeson](https://hackage.haskell.org/package/aeson).++See [hackage.haskell.org](https://hackage.haskell.org/package/aeson-flatten) for details.++## Installation++Run either `cabal install` or `stack install`. This is library, thus there is no executable available.++## Running tests++Tests can be run via `stack test`.++## Discalmer++Any feedback is very welcomed.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ aeson-flatten.cabal view
@@ -0,0 +1,40 @@+name:                aeson-flatten+version:             0.1.0.0+synopsis:            JSON flatten for Aeson+description:         Please see README.md+homepage:            https://github.com/githubuser/aeson-flatten#readme+license:             BSD3+license-file:        LICENSE+author:              Jiri Marsicek+maintainer:          jiri.marsicek@gmail.com+copyright:           2016 Jiri Marsicek+category:            Web, Text, JSON+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Data.Aeson.Flatten+  build-depends:       base >= 4.7 && < 5+                     , aeson+                     , text+                     , unordered-containers+  ghc-options:         -Wall+  default-language:    Haskell2010++test-suite aeson-flatten-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , aeson+                     , aeson-flatten+                     , bytestring+                     , hspec+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -Wall+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/githubuser/aeson-flatten
+ src/Data/Aeson/Flatten.hs view
@@ -0,0 +1,53 @@+-- |+-- Module: Data.Aeson.Prefix+-- Maintainer: Jiri Marsicek <jiri.marsicek@gmail.com>+--+-- Module provides 'flatten' which is used to flatten structure of 'Data.Aeson' JSON 'Value' as much as possible.+--+-- == Examples+--+-- === Basic objects+--+-- @{ "a": { "b": 1 } }@ results in @{ "b": 1 }@+--+-- @{ "a": { "b": { "c": 1 } } }@ results in @{ "c": 1 }@+--+-- @{ "a": [ { "b": { "c": 1 } }, { "b": { "c": 2 } } ] }@ results in @{ "a": [ { "c": 1 }, { "c": 2 } ] }@+--+-- === Name conflicts result in data loss+--+-- @{ "a": 1, "b": { "a": 2 } }@ results in @{ "a": 1 }@+--+-- * I don't know yet whether this is a feature or a bug :)+module Data.Aeson.Flatten+    ( flatten+    -- * Utility functions+    , isObject+    , mergeTo+    ) where++import Data.Aeson (Value(..))+import Data.Foldable (foldl')+import qualified Data.HashMap.Strict as Map (elems, filter, union)++-- |+-- Predicate for testing whether provided 'Value' is a 'Object'.+isObject :: Value -> Bool+isObject (Object _) = True+isObject _ = False++-- |+-- Merges keys from second 'Value' to first 'Value'.+-- In case of name conflict, values from first are preserved.+mergeTo :: Value -> Value -> Value+mergeTo (Object o1) (Object o2) = Object $ Map.union o1 o2+mergeTo o _ = o++-- |+-- Recursively Flattens the structure of the provided JSON 'Value'+flatten :: Value -> Value+flatten (Array a)  = Array $ flatten <$> a+flatten (Object o) = let flat = flatten <$> o+                         rest = Map.filter (not . isObject) flat+                      in foldl' mergeTo (Object rest) $ Map.elems flat+flatten v = v
+ test/Spec.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE OverloadedStrings #-}+import Test.Hspec++import Data.Aeson+import Data.Aeson.Flatten+import Data.Maybe (fromJust)+import Data.ByteString (ByteString)++decodeExample :: ByteString -> Value+decodeExample = fromJust . decodeStrict'++shouldResultIn :: ByteString -> ByteString -> Expectation+shouldResultIn input output = flatten (decodeExample input) `shouldBe` flatten (decodeExample output)++-- Test Cases++main :: IO ()+main = hspec $+  describe "Data.Aeson.Flatten" $+    describe "flatten" $ do+      it "works for empty object" $+        "{}" `shouldResultIn` "{}"+      it "works for simple object" $+        "{ \"a\": { \"b\": 1 } }" `shouldResultIn` "{ \"b\": 1 }"+      it "preserves values from more significant level in case of name clash" $+        "{ \"a\" : { \"b\": 1 }, \"b\": 2 }" `shouldResultIn` "{ \"b\": 2 }"+      it "works for one level flattening" $+        "{ \"a\": { \"b\": 1, \"c\": 2 } }" `shouldResultIn` "{ \"b\": 1, \"c\": 2 }"+      it "works for two level flattening" $+        "{ \"a\": { \"b\": { \"c\": 1 } } }" `shouldResultIn` "{ \"c\": 1 }"+      it "works for array with one level objects" $+        "{ \"a\": [ { \"b\": { \"c\": 1 } }, { \"b\": { \"c\": 234 } } ] }" `shouldResultIn` "{ \"a\": [ { \"c\": 1 }, { \"c\": 234 } ] }"