packages feed

aeson-pretty 0.7.2 → 0.8.0

raw patch · 3 files changed

+71/−25 lines, 3 filesdep +scientificdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: scientific

Dependency ranges changed: base

API changes (from Hackage documentation)

- Data.Aeson.Encode.Pretty: confCompare :: Config -> Text -> Text -> Ordering
- Data.Aeson.Encode.Pretty: confIndent :: Config -> Int
+ Data.Aeson.Encode.Pretty: Custom :: (Scientific -> Builder) -> NumberFormat
+ Data.Aeson.Encode.Pretty: Decimal :: NumberFormat
+ Data.Aeson.Encode.Pretty: Generic :: NumberFormat
+ Data.Aeson.Encode.Pretty: Scientific :: NumberFormat
+ Data.Aeson.Encode.Pretty: Spaces :: Int -> Indent
+ Data.Aeson.Encode.Pretty: Tab :: Indent
+ Data.Aeson.Encode.Pretty: [confCompare] :: Config -> Text -> Text -> Ordering
+ Data.Aeson.Encode.Pretty: [confIndent] :: Config -> Indent
+ Data.Aeson.Encode.Pretty: [confNumFormat] :: Config -> NumberFormat
+ Data.Aeson.Encode.Pretty: data Indent
+ Data.Aeson.Encode.Pretty: data NumberFormat
- Data.Aeson.Encode.Pretty: Config :: Int -> (Text -> Text -> Ordering) -> Config
+ Data.Aeson.Encode.Pretty: Config :: Indent -> (Text -> Text -> Ordering) -> NumberFormat -> Config

Files

Data/Aeson/Encode/Pretty.hs view
@@ -4,18 +4,19 @@ 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".@@ -60,23 +61,46 @@ import qualified Data.HashMap.Strict as H (toList) import Data.List (intersperse, sortBy, elemIndex) import Data.Maybe (fromMaybe)-import Data.Monoid ((<>), mconcat, mempty)-import Data.Ord+import Data.Monoid ((<>))+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) -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+  -- | Use decimal notation for values between 0.1 and 9,999,999, and scientific+  --   notation otherwise.+  = 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     }  -- |Sort keys by their order of appearance in the argument list.@@ -92,11 +116,12 @@ -- |The default configuration: indent by four spaces per level of nesting, do --  not sort objects by key. -----  > defConfig = Config { confIndent = 4, confCompare = mempty }+--  > defConfig = Config { confIndent = 4, confCompare = mempty, confNumFormat = Generic } defConfig :: Config-defConfig = Config { confIndent = 4, confCompare = mempty }+defConfig =+  Config {confIndent = Spaces 4, confCompare = mempty, confNumFormat = Generic} --- |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'.@@ -120,15 +145,26 @@ encodePrettyToTextBuilder' :: ToJSON a => Config -> a -> Builder encodePrettyToTextBuilder' Config{..} = fromValue st . toJSON   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)   fromValue :: PState -> Value -> Builder fromValue st@PState{..} = go   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 (H.toList m))+    go (Number x) = fromNumber st x     go v          = Aeson.encodeToTextBuilder v  fromCompound :: PState@@ -139,17 +175,25 @@ 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    -> formatScientificBuilder S.Generic Nothing x+  Scientific -> formatScientificBuilder S.Exponent Nothing x+  Decimal    -> formatScientificBuilder S.Fixed Nothing x+  Custom f   -> f x
aeson-pretty.cabal view
@@ -1,5 +1,5 @@ name:           aeson-pretty-version:        0.7.2+version:        0.8.0 license:        BSD3 license-file:   LICENSE category:       Text, Web, JSON, Pretty Printer@@ -43,6 +43,7 @@         aeson >= 0.7,         base >= 4.5,         bytestring >= 0.9,+        scientific >= 0.3,         vector >= 0.9,         text >= 0.11,         unordered-containers >= 0.1.3.0
cli-tool/Main.hs view
@@ -44,8 +44,9 @@ 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                       }         enc = if compact then encode else encodePretty' conf     interact $ unlines . map enc . values