module Data.JSON2.Pretty where
import Data.JSON2.Types
import Text.PrettyPrint
import Data.Ratio
import qualified Data.Map as Map
import Data.Map(Map)
import qualified Data.Set as Set
import Data.Set(Set)
class Show a => Pretty a where
pp :: a -> Doc
pp = text . show
pprint :: a -> String
pprint = render . pp
instance Pretty ()
instance Pretty Char
instance Pretty Int
instance Pretty Integer
instance Pretty Float
instance Pretty Double
instance Pretty Rational
instance Pretty String where
pp = text
instance Pretty a => Pretty (Maybe a) where
pp (Just x) = text "Just" <+> pp x
pp Nothing = text "Noting"
instance (Pretty a,Pretty b) => Pretty (Either a b) where
pp (Right x) = text "Right" <+> pp x
pp (Left x) = text "Left" <+> pp x
instance Pretty a => Pretty [a] where
pp xs = brackets $ fsep $ punctuate comma $ map pp xs
instance (Pretty k, Pretty v) => Pretty (Map k v) where
pp m = braces $ sep $ punctuate comma $ map ppair xs
where xs = Map.toList m
ppair (k,v) = pp k <> colon <+> pp v
instance Pretty a => Pretty (Set a) where
pp s = braces $ fsep $ punctuate comma $ map pp (Set.toList s)
instance (Pretty a, Pretty b) => Pretty (a, b) where
pp (a, b) = parens $ pp a <> comma <+> pp b
instance (Pretty a, Pretty b, Pretty c) => Pretty (a, b, c) where
pp (a, b, c) = parens $ pp a <> comma <+> pp b <> comma <+> pp c
instance (Pretty a, Pretty b, Pretty c, Pretty d) => Pretty (a, b, c, d) where
pp (a, b, c, d) = parens $ pp a <> comma <+> pp b <> comma <+> pp c
<> comma <+> pp d
instance (Pretty a, Pretty b, Pretty c, Pretty d, Pretty e)
=> Pretty (a, b, c, d, e) where
pp (a, b, c, d, e) = parens $ pp a <> comma <+> pp b <> comma <+> pp c
<> comma <+> pp d <> comma <+> pp e
instance Pretty Json where
pp (JNumber x)
| denominator x == 1 = text $ show (numerator x)
| otherwise = text $ show (fromRational x :: Double)
pp (JBool True) = text "true"
pp (JBool False) = text "false"
pp JNull = text "null"
pp (JString x) = doubleQuotes $ text $ escJString x
pp (JArray xs) = brackets $ fsep $ punctuate comma $ map pp xs
pp (JObject m)= braces $ sep $ punctuate comma $ map ppair xs
where xs = Map.toList m
ppair (k,v) = (doubleQuotes $ text k) <> colon <+> pp v