1{-# LANGUAGE DeriveDataTypeable, RecordWildCards, OverloadedStrings #-}
2module Main (main) where
3
4import Prelude hiding (interact, concat, unlines, null)
5import Data.Aeson (Value(..), json', encode)
6import Data.Aeson.Encode.Pretty
7import Data.Attoparsec.Lazy (Result(..), parse)
8import Data.ByteString.Lazy.Char8 (ByteString, interact, unlines, null)
9import Data.Version (showVersion)
10import Paths_aeson_pretty (version)
11import System.Console.CmdArgs
12
13
14data Options = Opts { compact :: Bool
15                    , indent  :: Int
16                    , sort    :: Bool
17                    }
18    deriving (Data, Typeable)
19
20opts :: Options
21opts = Opts
22    { compact = False &= help "Compact output."
23    , indent  = 4     &= help "Number of spaces per nesting-level (default 4)."
24    , sort    = False &= help "Sort objects by key (default: undefined order)."
25    }   &= program prog
26        &= summary smry
27        &= details info
28  where
29    prog = "aeson-pretty"
30    smry = prog++" "++showVersion version++": Pretty JSON, the easy way."
31
32info :: [String]
33info =
34    [ "Read JSON from stdin and pretty-print to stdout. The complementary "
35    , "compact-mode removes whitespace from the input."
36    , ""
37    , "(c) Falko Peters 2011"
38    , ""
39    , "License: BSD3, for details see the source-repository at"
40    , "http://www.github.com/informatikr/aeson-pretty."
41    , ""
42    ]
43
44main :: IO ()
45main = do
46    Opts{..} <- cmdArgs opts
47    let conf = Config { confIndent          = Spaces indent
48                      , confCompare         = if sort then compare else mempty
49                      , confNumFormat       = Generic
50                      , confTrailingNewline = False
51                      }
52        enc = if compact then encode else encodePretty' conf
53    interact $ unlines . map enc . values
54
55values :: ByteString -> [Value]
56values s = case parse json' s of
57            Done rest v     -> v : values rest
58            Fail rest _ _
59                | null rest -> []
60                | otherwise -> error "invalid json"
61