module Data.JSON2.Types
( Json (..)
, Jsons (..)
, toString
, escJString
)
where
import Data.Map (Map)
import qualified Data.Map as Map (toList)
import Data.Typeable (Typeable)
import Data.Ratio
data Json = JString String
| JNumber !Rational
| JBool !Bool
| JNull
| JArray [Json]
| JObject (Map String Json)
deriving (Eq, Ord, Typeable, Show, Read)
type Jsons = [Json]
toString :: Json -> String
toString (JNumber x)
| denominator x == 1 = show (numerator x)
| otherwise = show (fromRational x :: Double)
toString (JBool True) = "true"
toString (JBool False) = "false"
toString JNull = "null"
toString (JString x) = jStr x
toString (JArray []) = "[]"
toString (JArray (x:xs)) = concat [ "[", toString x, go, "]" ]
where
go = concat $ map (\x -> "," ++ toString x) xs
toString (JObject m) = concat ["{", go (Map.toList m), "}"]
where
go [] = ""
go (x:xs) = go' x ++ concat [go'' v | v <- xs]
go' (k, v) = concat [jStr k, ":", toString v]
go'' (k, v) = concat [",", jStr k, ":", toString v]
jStr x = "\"" ++ escJString x ++ "\""
escJString :: String -> String
escJString = concat . map (escJChar)
escJChar c = case c of
'\n' -> "\\n"
'\b' -> "\\b"
'\f' -> "\\f"
'\t' -> "\\t"
'\r' -> "\\r"
'\\' -> "\\\\"
'\"' -> "\\\""
_ -> [c]