{-# LANGUAGE IncoherentInstances, TypeSynonymInstances #-} -- | Class and Instances for pretty printing Your data. -- -- Minimal definition for instances @Pretty@ - method @pp@ . 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 -- Instances instance Pretty () instance Pretty Char instance Pretty Int instance Pretty Integer instance Pretty Float instance Pretty Double instance Pretty Rational -- String instance Pretty String where pp = text -- Maybe instance Pretty a => Pretty (Maybe a) where pp (Just x) = text "Just" <+> pp x pp Nothing = text "Noting" -- Either instance (Pretty a,Pretty b) => Pretty (Either a b) where pp (Right x) = text "Right" <+> pp x pp (Left x) = text "Left" <+> pp x -- List instance Pretty a => Pretty [a] where pp xs = brackets $ fsep $ punctuate comma $ map pp xs -- Map 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 -- Set instance Pretty a => Pretty (Set a) where pp s = braces $ fsep $ punctuate comma $ map pp (Set.toList s) -- Tuples 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 -- JSON 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