From c606f874fb6642794266b3d49ad8b777070edab8 Mon Sep 17 00:00:00 2001 From: Stephen Morgan Date: Wed, 21 Jul 2021 12:30:01 +1000 Subject: [PATCH] imp: json: The keys of JSON objects are now displayed in alphabetical order, making it stable across different systems and compilers. --- hledger-lib/Hledger/Data/Json.hs | 14 +++--- hledger/test/json.test | 86 ++++++++++++++++---------------- 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/hledger-lib/Hledger/Data/Json.hs b/hledger-lib/Hledger/Data/Json.hs index e89a5b5b1..f17645ec9 100644 --- a/hledger-lib/Hledger/Data/Json.hs +++ b/hledger-lib/Hledger/Data/Json.hs @@ -34,13 +34,13 @@ module Hledger.Data.Json ( ) where import Data.Aeson -import Data.Aeson.Encode.Pretty (encodePrettyToTextBuilder) +import Data.Aeson.Encode.Pretty (Config(..), Indent(..), NumberFormat(..), + encodePretty', encodePrettyToTextBuilder') --import Data.Aeson.TH import qualified Data.ByteString.Lazy as BL import Data.Decimal (DecimalRaw(..), roundTo) import Data.Maybe (fromMaybe) import qualified Data.Text.Lazy as TL -import qualified Data.Text.Lazy.IO as TL import qualified Data.Text.Lazy.Builder as TB import GHC.Generics (Generic) import System.Time (ClockTime) @@ -259,15 +259,18 @@ instance FromJSON (DecimalRaw Integer) -- Utilities +-- | Config for pretty printing JSON output. +jsonConf :: Config +jsonConf = Config{confIndent=Spaces 4,confCompare=compare, confNumFormat=Generic, confTrailingNewline=True} + -- | Show a JSON-convertible haskell value as pretty-printed JSON text. toJsonText :: ToJSON a => a -> TL.Text -toJsonText = TB.toLazyText . (<> TB.fromText "\n") . encodePrettyToTextBuilder +toJsonText = TB.toLazyText . encodePrettyToTextBuilder' jsonConf -- | Write a JSON-convertible haskell value to a pretty-printed JSON file. -- Eg: writeJsonFile "a.json" nulltransaction writeJsonFile :: ToJSON a => FilePath -> a -> IO () -writeJsonFile f = TL.writeFile f . toJsonText --- we write with Text and read with ByteString, is that fine ? +writeJsonFile f = BL.writeFile f . encodePretty' jsonConf -- | Read a JSON file and decode it to the target type, or raise an error if we can't. -- Eg: readJsonFile "a.json" :: IO Transaction @@ -280,4 +283,3 @@ readJsonFile f = do case fromJSON v :: FromJSON a => Result a of Error e -> error e Success t -> return t - diff --git a/hledger/test/json.test b/hledger/test/json.test index 1a970981f..75b77aa0c 100644 --- a/hledger/test/json.test +++ b/hledger/test/json.test @@ -10,52 +10,52 @@ $ hledger -f- reg --output-format=json null, "", { - "pbalanceassertion": null, - "pstatus": "Unmarked", + "paccount": "a", "pamount": [ { - "aprice": null, "acommodity": "AAA", - "aquantity": { - "floatingPoint": 1, - "decimalPlaces": 1, - "decimalMantissa": 10 - }, "aismultiplier": false, + "aprice": null, + "aquantity": { + "decimalMantissa": 10, + "decimalPlaces": 1, + "floatingPoint": 1 + }, "astyle": { "ascommodityside": "R", - "asdigitgroups": null, "ascommodityspaced": true, - "asprecision": 1, - "asdecimalpoint": "." + "asdecimalpoint": ".", + "asdigitgroups": null, + "asprecision": 1 } } ], - "ptransaction_": "1", - "paccount": "a", - "pdate": null, - "ptype": "VirtualPosting", + "pbalanceassertion": null, "pcomment": "", + "pdate": null, "pdate2": null, + "poriginal": null, + "pstatus": "Unmarked", "ptags": [], - "poriginal": null + "ptransaction_": "1", + "ptype": "VirtualPosting" }, [ { - "aprice": null, "acommodity": "AAA", - "aquantity": { - "floatingPoint": 1, - "decimalPlaces": 1, - "decimalMantissa": 10 - }, "aismultiplier": false, + "aprice": null, + "aquantity": { + "decimalMantissa": 10, + "decimalPlaces": 1, + "floatingPoint": 1 + }, "astyle": { "ascommodityside": "R", - "asdigitgroups": null, "ascommodityspaced": true, - "asprecision": 1, - "asdecimalpoint": "." + "asdecimalpoint": ".", + "asdigitgroups": null, + "asprecision": 1 } } ] @@ -72,20 +72,20 @@ $ hledger -f- bal --output-format=json 0, [ { - "aprice": null, "acommodity": "AAA", - "aquantity": { - "floatingPoint": 1, - "decimalPlaces": 1, - "decimalMantissa": 10 - }, "aismultiplier": false, + "aprice": null, + "aquantity": { + "decimalMantissa": 10, + "decimalPlaces": 1, + "floatingPoint": 1 + }, "astyle": { "ascommodityside": "R", - "asdigitgroups": null, "ascommodityspaced": true, - "asprecision": 1, - "asdecimalpoint": "." + "asdecimalpoint": ".", + "asdigitgroups": null, + "asprecision": 1 } } ] @@ -93,20 +93,20 @@ $ hledger -f- bal --output-format=json ], [ { - "aprice": null, "acommodity": "AAA", - "aquantity": { - "floatingPoint": 1, - "decimalPlaces": 1, - "decimalMantissa": 10 - }, "aismultiplier": false, + "aprice": null, + "aquantity": { + "decimalMantissa": 10, + "decimalPlaces": 1, + "floatingPoint": 1 + }, "astyle": { "ascommodityside": "R", - "asdigitgroups": null, "ascommodityspaced": true, - "asprecision": 1, - "asdecimalpoint": "." + "asdecimalpoint": ".", + "asdigitgroups": null, + "asprecision": 1 } } ]