packages feed

aeson-pretty 0.7.2 → 0.8.11

raw patch · 5 files changed

Files

+ CHANGELOG.markdown view
@@ -0,0 +1,12 @@+# aeson-pretty changelog++## 0.8.11+ * Dropped support for Aeson 1.4 and older+ * Added support for Aeson 2.3+ * Added support for Aeson 2.2++## 0.8.10+ * Added support for Aeson 2.1++## 0.8.9+ * Added support for Aeson 2.0
Data/Aeson/Encode/Pretty.hs view
@@ -1,21 +1,22 @@-{-# LANGUAGE OverloadedStrings, RecordWildCards #-}+{-# LANGUAGE OverloadedStrings, RecordWildCards, CPP #-}  -- |Aeson-compatible pretty-printing of JSON 'Value's. module Data.Aeson.Encode.Pretty (     -- * Simple Pretty-Printing     encodePretty, encodePrettyToTextBuilder,-    +     -- * Pretty-Printing with Configuration Options     encodePretty', encodePrettyToTextBuilder',     Config (..), defConfig,+    Indent(..), NumberFormat(..),     -- ** Sorting Keys in Objects-    -- |With the Aeson library, the order of keys in objects is undefined due+    -- |With the Aeson library, the order of keys in objects is undefined due to     --  objects being implemented as HashMaps. To allow user-specified key     --  orders in the pretty-printed JSON, 'encodePretty'' can be configured     --  with a comparison function. These comparison functions can be composed     --  using the 'Monoid' interface. Some other useful helper functions to keep     --  in mind are 'comparing' and 'on'.-    --  +    --     --  Consider the following deliberately convoluted example, demonstrating     --  the use of comparison functions:     --@@ -43,7 +44,7 @@     --  >   "quux": ...,     --  > }     ---    +     mempty,     -- |Serves as an order-preserving (non-)sort function. Re-exported from     --  "Data.Monoid".@@ -53,30 +54,68 @@     keyOrder ) where +#if MIN_VERSION_aeson(2,0,0)+import qualified Data.Aeson.Key as AK+import qualified Data.Aeson.KeyMap as AKM+#endif import Data.Aeson (Value(..), ToJSON(..))-import qualified Data.Aeson.Encode as Aeson+import qualified Data.Aeson.Text as Aeson import Data.ByteString.Lazy (ByteString) import Data.Function (on)+#if !MIN_VERSION_aeson(2,0,0) import qualified Data.HashMap.Strict as H (toList)+#endif import Data.List (intersperse, sortBy, elemIndex) import Data.Maybe (fromMaybe)-import Data.Monoid ((<>), mconcat, mempty)-import Data.Ord+#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif+import qualified Data.Scientific as S (Scientific, FPFormat(..))+import Data.Ord (comparing) import Data.Text (Text) import Data.Text.Lazy.Builder (Builder, toLazyText)+import Data.Text.Lazy.Builder.Scientific (formatScientificBuilder) import Data.Text.Lazy.Encoding (encodeUtf8) import qualified Data.Vector as V (toList)+import Prelude ()+import Prelude.Compat -data PState = PState { pstIndent :: Int-                     , pstLevel  :: Int-                     , pstSort   :: [(Text, Value)] -> [(Text, Value)]++data PState = PState { pLevel     :: Int+                     , pIndent    :: Builder+                     , pNewline   :: Builder+                     , pItemSep   :: Builder+                     , pKeyValSep :: Builder+                     , pNumFormat :: NumberFormat+                     , pSort      :: [(Text, Value)] -> [(Text, Value)]                      } +-- | Indentation per level of nesting. @'Spaces' 0@ removes __all__ whitespace+--   from the output.+data Indent = Spaces Int | Tab++data NumberFormat+  -- | For numbers with absolute value less than 1e19, this follows the standard+  -- behaviour of the 'Data.Aeson.encode' function. Uses integer literals for+  -- integers (1, 2, 3...), simple decimals for fractional values between 0.1+  -- and 9,999,999, and scientific notation otherwise. For numbers with an+  -- absolute value larger than 1e19, always uses scientific notation.+  = Generic+  -- | Scientific notation (e.g. 2.3e123).+  | Scientific+  -- | Standard decimal notation+  | Decimal+  -- | Custom formatting function+  | Custom (S.Scientific -> Builder)+ data Config = Config-    { confIndent  :: Int-      -- ^ Indentation spaces per level of nesting+    { confIndent  :: Indent+      -- ^ Indentation per level of nesting     , confCompare :: Text -> Text -> Ordering       -- ^ Function used to sort keys in objects+    , confNumFormat :: NumberFormat+    , confTrailingNewline :: Bool+      -- ^ Whether to add a trailing newline to the output     }  -- |Sort keys by their order of appearance in the argument list.@@ -90,13 +129,14 @@   -- |The default configuration: indent by four spaces per level of nesting, do---  not sort objects by key.+--  not sort objects by key, do not add trailing newline. -----  > defConfig = Config { confIndent = 4, confCompare = mempty }+--  > defConfig = Config { confIndent = Spaces 4, confCompare = mempty, confNumFormat = Generic, confTrailingNewline = False } defConfig :: Config-defConfig = Config { confIndent = 4, confCompare = mempty }+defConfig =+  Config {confIndent = Spaces 4, confCompare = mempty, confNumFormat = Generic, confTrailingNewline = False} --- |A drop-in replacement for aeson's 'Aeson.encode' function, producing +-- |A drop-in replacement for aeson's 'Aeson.encode' function, producing --  JSON-ByteStrings for human readers. -- --  Follows the default configuration in 'defConfig'.@@ -115,22 +155,40 @@ encodePrettyToTextBuilder :: ToJSON a => a -> Builder encodePrettyToTextBuilder = encodePrettyToTextBuilder' defConfig --- |A variant of 'encodeToTextBuilder' that takes an additional configuration+-- |A variant of 'Aeson.encodeToTextBuilder' that takes an additional configuration --  parameter. encodePrettyToTextBuilder' :: ToJSON a => Config -> a -> Builder-encodePrettyToTextBuilder' Config{..} = fromValue st . toJSON+encodePrettyToTextBuilder' Config{..} x = fromValue st (toJSON x) <> trail   where-    st       = PState confIndent 0 condSort-    condSort = sortBy (confCompare `on` fst)+    st      = PState 0 indent newline itemSep kvSep confNumFormat sortFn+    indent  = case confIndent of+                Spaces n -> mconcat (replicate n " ")+                Tab      -> "\t"+    newline = case confIndent of+                Spaces 0 -> ""+                _        -> "\n"+    itemSep = ","+    kvSep   = case confIndent of+                Spaces 0 -> ":"+                _        -> ": "+    sortFn  = sortBy (confCompare `on` fst)+    trail   = if confTrailingNewline then "\n" else ""   fromValue :: PState -> Value -> Builder-fromValue st@PState{..} = go+fromValue st@PState{..} val = go val   where     go (Array v)  = fromCompound st ("[","]") fromValue (V.toList v)-    go (Object m) = fromCompound st ("{","}") fromPair (pstSort (H.toList m))+    go (Object m) = fromCompound st ("{","}") fromPair (pSort (toList' m))+    go (Number x) = fromNumber st x     go v          = Aeson.encodeToTextBuilder v +#if MIN_VERSION_aeson(2,0,0)+    toList' = fmap (\(k, v) -> (AK.toText k, v)) . AKM.toList+#else+    toList' = H.toList+#endif+ fromCompound :: PState              -> (Builder, Builder)              -> (PState -> a -> Builder)@@ -139,17 +197,27 @@ fromCompound st@PState{..} (delimL,delimR) fromItem items = mconcat     [ delimL     , if null items then mempty-        else "\n" <> items' <> "\n" <> fromIndent st+        else pNewline <> items' <> pNewline <> fromIndent st     , delimR     ]   where-    items' = mconcat . intersperse ",\n" $+    items' = mconcat . intersperse (pItemSep <> pNewline) $                 map (\item -> fromIndent st' <> fromItem st' item)                     items-    st' = st { pstLevel = pstLevel + 1 }+    st' = st { pLevel = pLevel + 1}  fromPair :: PState -> (Text, Value) -> Builder-fromPair st (k,v) = Aeson.encodeToTextBuilder (toJSON k) <> ": " <> fromValue st v+fromPair st (k,v) =+  Aeson.encodeToTextBuilder (toJSON k) <> pKeyValSep st <> fromValue st v  fromIndent :: PState -> Builder-fromIndent PState{..} = mconcat $ replicate (pstIndent * pstLevel) " "+fromIndent PState{..} = mconcat (replicate pLevel pIndent)++fromNumber :: PState -> S.Scientific -> Builder+fromNumber st x = case pNumFormat st of+  Generic+    | (x > 1.0e19 || x < -1.0e19) -> formatScientificBuilder S.Exponent Nothing x+    | otherwise -> Aeson.encodeToTextBuilder $ Number x+  Scientific -> formatScientificBuilder S.Exponent Nothing x+  Decimal    -> formatScientificBuilder S.Fixed Nothing x+  Custom f   -> f x
README.markdown view
@@ -18,6 +18,9 @@  * `git clone git://github.com/informatikr/aeson-pretty.git` +# Aeson / GHC support+We support all GHCs supported by the latest Aeson release. This in turn determines which Aeson releases we support.+ # Authors -This library is written and maintained by Falko Peters, <falko.peters@gmail.com>.+This library is written by Falko Peters <falko.peters@gmail.com> and maintained by Martijn Bastiaan <martijn@qbaylogic.com>.
aeson-pretty.cabal view
@@ -1,20 +1,20 @@+cabal-version:  2.0 name:           aeson-pretty-version:        0.7.2+version:        0.8.11 license:        BSD3 license-file:   LICENSE category:       Text, Web, JSON, Pretty Printer copyright:      Copyright 2011 Falko Peters author:         Falko Peters <falko.peters@gmail.com>-maintainer:     Falko Peters <falko.peters@gmail.com>+maintainer:     Martijn Bastiaan <martijn@hmbastiaan.nl> stability:      experimental-cabal-version:  >= 1.8 homepage:       http://github.com/informatikr/aeson-pretty bug-reports:    http://github.com/informatikr/aeson-pretty/issues build-type:     Simple synopsis:       JSON pretty-printing library and command-line tool. description:     A JSON pretty-printing library compatible with aeson as well as-    a command-line tool to improve readabilty of streams of JSON data.+    a command-line tool to improve readability of streams of JSON data.     .     The /library/ provides the function "encodePretty". It is a drop-in     replacement for aeson's "encode" function, producing JSON-ByteStrings for@@ -22,36 +22,41 @@     .     The /command-line tool/ reads JSON from stdin and writes prettified JSON     to stdout. It also offers a complementary "compact"-mode, essentially the-    opposite of pretty-printing. If you specify @-flib-only@ like this-    .-        > cabal install -flib-only aeson-pretty-    .-    the command-line tool will NOT be installed.+    opposite of pretty-printing.  extra-source-files:     README.markdown +extra-doc-files:+    CHANGELOG.markdown+ flag lib-only     description: Only build/install the library, NOT the command-line tool.     default: False+    manual: True  library     exposed-modules:         Data.Aeson.Encode.Pretty      build-depends:-        aeson >= 0.7,-        base >= 4.5,+        aeson >=1.5  && <2.4,+        base >= 4.10 && < 4.23,+        base-compat >= 0.9,         bytestring >= 0.9,+        scientific >= 0.3,         vector >= 0.9,         text >= 0.11,-        unordered-containers >= 0.1.3.0+        unordered-containers >= 0.2.14.0      ghc-options: -Wall+    default-language: Haskell2010  executable aeson-pretty     hs-source-dirs: cli-tool     main-is: Main.hs+    other-modules: Paths_aeson_pretty+    autogen-modules: Paths_aeson_pretty      if flag(lib-only)         buildable: False@@ -60,12 +65,13 @@             aeson >= 0.6,             aeson-pretty,             attoparsec >= 0.10,-            base == 4.*,+            attoparsec-aeson,+            base >= 4.10 && < 4.23,             bytestring >= 0.9,             cmdargs >= 0.7      ghc-options: -Wall-    ghc-prof-options: -auto-all+    default-language: Haskell2010  source-repository head     type:     git
cli-tool/Main.hs view
@@ -1,9 +1,14 @@-{-# LANGUAGE DeriveDataTypeable, RecordWildCards, OverloadedStrings #-}+{-# LANGUAGE CPP, DeriveDataTypeable, RecordWildCards, OverloadedStrings, PackageImports #-} module Main (main) where  import Prelude hiding (interact, concat, unlines, null)-import Data.Aeson (Value(..), json', encode)+import Data.Aeson (Value(..), encode) import Data.Aeson.Encode.Pretty+#if MIN_VERSION_aeson(2,2,0)+import "attoparsec-aeson" Data.Aeson.Parser.Internal (value')+#else+import "aeson" Data.Aeson.Parser.Internal (value')+#endif import Data.Attoparsec.Lazy (Result(..), parse) import Data.ByteString.Lazy.Char8 (ByteString, interact, unlines, null) import Data.Version (showVersion)@@ -15,7 +20,11 @@                     , indent  :: Int                     , sort    :: Bool                     }+#if __GLASGOW_HASKELL__ >= 912+    deriving (Data)+#else     deriving (Data, Typeable)+#endif  opts :: Options opts = Opts@@ -44,14 +53,16 @@ main :: IO () main = do     Opts{..} <- cmdArgs opts-    let conf = Config { confIndent  = indent-                      , confCompare = if sort then compare else mempty+    let conf = Config { confIndent          = Spaces indent+                      , confCompare         = if sort then compare else mempty+                      , confNumFormat       = Generic+                      , confTrailingNewline = False                       }         enc = if compact then encode else encodePretty' conf     interact $ unlines . map enc . values  values :: ByteString -> [Value]-values s = case parse json' s of+values s = case parse value' s of             Done rest v     -> v : values rest             Fail rest _ _                 | null rest -> []