{-# LANGUAGE DeriveDataTypeable #-}
-- | The types to encode Haskell values.

module Text.JSON5.Types (

    -- * JSON5 Types
    JSValue(..)
  , JSNumber(..)
  , fromJSRational
  , fromJSInfNaN

    -- * Wrapper Types
  , JSString(..)
  , toJSString

  , JSObject(..)
  , toJSObject
  , get_field
  , set_field

  ) where

import Data.Typeable (Typeable)
import Data.String (IsString(..))

data JSValue
    = JSNull
    | JSBool     !Bool
    | JSNumber   JSNumber
    | JSString   JSString{-wrapped-}
    | JSArray    [JSValue]
    | JSObject   (JSObject JSValue)
    deriving (JSValue -> JSValue -> Bool
(JSValue -> JSValue -> Bool)
-> (JSValue -> JSValue -> Bool) -> Eq JSValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JSValue -> JSValue -> Bool
$c/= :: JSValue -> JSValue -> Bool
== :: JSValue -> JSValue -> Bool
$c== :: JSValue -> JSValue -> Bool
Eq, Eq JSValue
Eq JSValue
-> (JSValue -> JSValue -> Ordering)
-> (JSValue -> JSValue -> Bool)
-> (JSValue -> JSValue -> Bool)
-> (JSValue -> JSValue -> Bool)
-> (JSValue -> JSValue -> Bool)
-> (JSValue -> JSValue -> JSValue)
-> (JSValue -> JSValue -> JSValue)
-> Ord JSValue
JSValue -> JSValue -> Bool
JSValue -> JSValue -> Ordering
JSValue -> JSValue -> JSValue
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: JSValue -> JSValue -> JSValue
$cmin :: JSValue -> JSValue -> JSValue
max :: JSValue -> JSValue -> JSValue
$cmax :: JSValue -> JSValue -> JSValue
>= :: JSValue -> JSValue -> Bool
$c>= :: JSValue -> JSValue -> Bool
> :: JSValue -> JSValue -> Bool
$c> :: JSValue -> JSValue -> Bool
<= :: JSValue -> JSValue -> Bool
$c<= :: JSValue -> JSValue -> Bool
< :: JSValue -> JSValue -> Bool
$c< :: JSValue -> JSValue -> Bool
compare :: JSValue -> JSValue -> Ordering
$ccompare :: JSValue -> JSValue -> Ordering
$cp1Ord :: Eq JSValue
Ord, Int -> JSValue -> ShowS
[JSValue] -> ShowS
JSValue -> String
(Int -> JSValue -> ShowS)
-> (JSValue -> String) -> ([JSValue] -> ShowS) -> Show JSValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JSValue] -> ShowS
$cshowList :: [JSValue] -> ShowS
show :: JSValue -> String
$cshow :: JSValue -> String
showsPrec :: Int -> JSValue -> ShowS
$cshowsPrec :: Int -> JSValue -> ShowS
Show, ReadPrec [JSValue]
ReadPrec JSValue
Int -> ReadS JSValue
ReadS [JSValue]
(Int -> ReadS JSValue)
-> ReadS [JSValue]
-> ReadPrec JSValue
-> ReadPrec [JSValue]
-> Read JSValue
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [JSValue]
$creadListPrec :: ReadPrec [JSValue]
readPrec :: ReadPrec JSValue
$creadPrec :: ReadPrec JSValue
readList :: ReadS [JSValue]
$creadList :: ReadS [JSValue]
readsPrec :: Int -> ReadS JSValue
$creadsPrec :: Int -> ReadS JSValue
Read, Typeable)

data JSNumber
    = JSRational !Rational
    | JSInfNaN   !Float
    deriving (JSNumber -> JSNumber -> Bool
(JSNumber -> JSNumber -> Bool)
-> (JSNumber -> JSNumber -> Bool) -> Eq JSNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JSNumber -> JSNumber -> Bool
$c/= :: JSNumber -> JSNumber -> Bool
== :: JSNumber -> JSNumber -> Bool
$c== :: JSNumber -> JSNumber -> Bool
Eq, Eq JSNumber
Eq JSNumber
-> (JSNumber -> JSNumber -> Ordering)
-> (JSNumber -> JSNumber -> Bool)
-> (JSNumber -> JSNumber -> Bool)
-> (JSNumber -> JSNumber -> Bool)
-> (JSNumber -> JSNumber -> Bool)
-> (JSNumber -> JSNumber -> JSNumber)
-> (JSNumber -> JSNumber -> JSNumber)
-> Ord JSNumber
JSNumber -> JSNumber -> Bool
JSNumber -> JSNumber -> Ordering
JSNumber -> JSNumber -> JSNumber
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: JSNumber -> JSNumber -> JSNumber
$cmin :: JSNumber -> JSNumber -> JSNumber
max :: JSNumber -> JSNumber -> JSNumber
$cmax :: JSNumber -> JSNumber -> JSNumber
>= :: JSNumber -> JSNumber -> Bool
$c>= :: JSNumber -> JSNumber -> Bool
> :: JSNumber -> JSNumber -> Bool
$c> :: JSNumber -> JSNumber -> Bool
<= :: JSNumber -> JSNumber -> Bool
$c<= :: JSNumber -> JSNumber -> Bool
< :: JSNumber -> JSNumber -> Bool
$c< :: JSNumber -> JSNumber -> Bool
compare :: JSNumber -> JSNumber -> Ordering
$ccompare :: JSNumber -> JSNumber -> Ordering
$cp1Ord :: Eq JSNumber
Ord, Int -> JSNumber -> ShowS
[JSNumber] -> ShowS
JSNumber -> String
(Int -> JSNumber -> ShowS)
-> (JSNumber -> String) -> ([JSNumber] -> ShowS) -> Show JSNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JSNumber] -> ShowS
$cshowList :: [JSNumber] -> ShowS
show :: JSNumber -> String
$cshow :: JSNumber -> String
showsPrec :: Int -> JSNumber -> ShowS
$cshowsPrec :: Int -> JSNumber -> ShowS
Show, ReadPrec [JSNumber]
ReadPrec JSNumber
Int -> ReadS JSNumber
ReadS [JSNumber]
(Int -> ReadS JSNumber)
-> ReadS [JSNumber]
-> ReadPrec JSNumber
-> ReadPrec [JSNumber]
-> Read JSNumber
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [JSNumber]
$creadListPrec :: ReadPrec [JSNumber]
readPrec :: ReadPrec JSNumber
$creadPrec :: ReadPrec JSNumber
readList :: ReadS [JSNumber]
$creadList :: ReadS [JSNumber]
readsPrec :: Int -> ReadS JSNumber
$creadsPrec :: Int -> ReadS JSNumber
Read, Typeable)

fromJSRational :: Rational -> JSValue
fromJSRational :: Rational -> JSValue
fromJSRational = JSNumber -> JSValue
JSNumber (JSNumber -> JSValue)
-> (Rational -> JSNumber) -> Rational -> JSValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> JSNumber
JSRational

fromJSInfNaN :: Float -> JSValue
fromJSInfNaN :: Float -> JSValue
fromJSInfNaN = JSNumber -> JSValue
JSNumber (JSNumber -> JSValue) -> (Float -> JSNumber) -> Float -> JSValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> JSNumber
JSInfNaN

newtype JSString = JSONString { JSString -> String
fromJSString :: String }
    deriving (JSString -> JSString -> Bool
(JSString -> JSString -> Bool)
-> (JSString -> JSString -> Bool) -> Eq JSString
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JSString -> JSString -> Bool
$c/= :: JSString -> JSString -> Bool
== :: JSString -> JSString -> Bool
$c== :: JSString -> JSString -> Bool
Eq, Eq JSString
Eq JSString
-> (JSString -> JSString -> Ordering)
-> (JSString -> JSString -> Bool)
-> (JSString -> JSString -> Bool)
-> (JSString -> JSString -> Bool)
-> (JSString -> JSString -> Bool)
-> (JSString -> JSString -> JSString)
-> (JSString -> JSString -> JSString)
-> Ord JSString
JSString -> JSString -> Bool
JSString -> JSString -> Ordering
JSString -> JSString -> JSString
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: JSString -> JSString -> JSString
$cmin :: JSString -> JSString -> JSString
max :: JSString -> JSString -> JSString
$cmax :: JSString -> JSString -> JSString
>= :: JSString -> JSString -> Bool
$c>= :: JSString -> JSString -> Bool
> :: JSString -> JSString -> Bool
$c> :: JSString -> JSString -> Bool
<= :: JSString -> JSString -> Bool
$c<= :: JSString -> JSString -> Bool
< :: JSString -> JSString -> Bool
$c< :: JSString -> JSString -> Bool
compare :: JSString -> JSString -> Ordering
$ccompare :: JSString -> JSString -> Ordering
$cp1Ord :: Eq JSString
Ord, Int -> JSString -> ShowS
[JSString] -> ShowS
JSString -> String
(Int -> JSString -> ShowS)
-> (JSString -> String) -> ([JSString] -> ShowS) -> Show JSString
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JSString] -> ShowS
$cshowList :: [JSString] -> ShowS
show :: JSString -> String
$cshow :: JSString -> String
showsPrec :: Int -> JSString -> ShowS
$cshowsPrec :: Int -> JSString -> ShowS
Show, ReadPrec [JSString]
ReadPrec JSString
Int -> ReadS JSString
ReadS [JSString]
(Int -> ReadS JSString)
-> ReadS [JSString]
-> ReadPrec JSString
-> ReadPrec [JSString]
-> Read JSString
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [JSString]
$creadListPrec :: ReadPrec [JSString]
readPrec :: ReadPrec JSString
$creadPrec :: ReadPrec JSString
readList :: ReadS [JSString]
$creadList :: ReadS [JSString]
readsPrec :: Int -> ReadS JSString
$creadsPrec :: Int -> ReadS JSString
Read, Typeable)

toJSString :: String -> JSString
toJSString :: String -> JSString
toJSString = String -> JSString
JSONString

instance IsString JSString where
  fromString :: String -> JSString
fromString = String -> JSString
toJSString

instance IsString JSValue where
  fromString :: String -> JSValue
fromString = JSString -> JSValue
JSString (JSString -> JSValue) -> (String -> JSString) -> String -> JSValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> JSString
forall a. IsString a => String -> a
fromString

newtype JSObject a = JSONObject { JSObject a -> [(String, a)]
fromJSObject :: [(String, a)] }
    deriving (JSObject a -> JSObject a -> Bool
(JSObject a -> JSObject a -> Bool)
-> (JSObject a -> JSObject a -> Bool) -> Eq (JSObject a)
forall a. Eq a => JSObject a -> JSObject a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JSObject a -> JSObject a -> Bool
$c/= :: forall a. Eq a => JSObject a -> JSObject a -> Bool
== :: JSObject a -> JSObject a -> Bool
$c== :: forall a. Eq a => JSObject a -> JSObject a -> Bool
Eq, Eq (JSObject a)
Eq (JSObject a)
-> (JSObject a -> JSObject a -> Ordering)
-> (JSObject a -> JSObject a -> Bool)
-> (JSObject a -> JSObject a -> Bool)
-> (JSObject a -> JSObject a -> Bool)
-> (JSObject a -> JSObject a -> Bool)
-> (JSObject a -> JSObject a -> JSObject a)
-> (JSObject a -> JSObject a -> JSObject a)
-> Ord (JSObject a)
JSObject a -> JSObject a -> Bool
JSObject a -> JSObject a -> Ordering
JSObject a -> JSObject a -> JSObject a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (JSObject a)
forall a. Ord a => JSObject a -> JSObject a -> Bool
forall a. Ord a => JSObject a -> JSObject a -> Ordering
forall a. Ord a => JSObject a -> JSObject a -> JSObject a
min :: JSObject a -> JSObject a -> JSObject a
$cmin :: forall a. Ord a => JSObject a -> JSObject a -> JSObject a
max :: JSObject a -> JSObject a -> JSObject a
$cmax :: forall a. Ord a => JSObject a -> JSObject a -> JSObject a
>= :: JSObject a -> JSObject a -> Bool
$c>= :: forall a. Ord a => JSObject a -> JSObject a -> Bool
> :: JSObject a -> JSObject a -> Bool
$c> :: forall a. Ord a => JSObject a -> JSObject a -> Bool
<= :: JSObject a -> JSObject a -> Bool
$c<= :: forall a. Ord a => JSObject a -> JSObject a -> Bool
< :: JSObject a -> JSObject a -> Bool
$c< :: forall a. Ord a => JSObject a -> JSObject a -> Bool
compare :: JSObject a -> JSObject a -> Ordering
$ccompare :: forall a. Ord a => JSObject a -> JSObject a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (JSObject a)
Ord, Int -> JSObject a -> ShowS
[JSObject a] -> ShowS
JSObject a -> String
(Int -> JSObject a -> ShowS)
-> (JSObject a -> String)
-> ([JSObject a] -> ShowS)
-> Show (JSObject a)
forall a. Show a => Int -> JSObject a -> ShowS
forall a. Show a => [JSObject a] -> ShowS
forall a. Show a => JSObject a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JSObject a] -> ShowS
$cshowList :: forall a. Show a => [JSObject a] -> ShowS
show :: JSObject a -> String
$cshow :: forall a. Show a => JSObject a -> String
showsPrec :: Int -> JSObject a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> JSObject a -> ShowS
Show, ReadPrec [JSObject a]
ReadPrec (JSObject a)
Int -> ReadS (JSObject a)
ReadS [JSObject a]
(Int -> ReadS (JSObject a))
-> ReadS [JSObject a]
-> ReadPrec (JSObject a)
-> ReadPrec [JSObject a]
-> Read (JSObject a)
forall a. Read a => ReadPrec [JSObject a]
forall a. Read a => ReadPrec (JSObject a)
forall a. Read a => Int -> ReadS (JSObject a)
forall a. Read a => ReadS [JSObject a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [JSObject a]
$creadListPrec :: forall a. Read a => ReadPrec [JSObject a]
readPrec :: ReadPrec (JSObject a)
$creadPrec :: forall a. Read a => ReadPrec (JSObject a)
readList :: ReadS [JSObject a]
$creadList :: forall a. Read a => ReadS [JSObject a]
readsPrec :: Int -> ReadS (JSObject a)
$creadsPrec :: forall a. Read a => Int -> ReadS (JSObject a)
Read, Typeable )

toJSObject :: [(String,a)] -> JSObject a
toJSObject :: [(String, a)] -> JSObject a
toJSObject = [(String, a)] -> JSObject a
forall a. [(String, a)] -> JSObject a
JSONObject

get_field :: JSObject a -> String -> Maybe a
get_field :: JSObject a -> String -> Maybe a
get_field (JSONObject [(String, a)]
xs) String
x = String -> [(String, a)] -> Maybe a
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
x [(String, a)]
xs

set_field :: JSObject a -> String -> a -> JSObject a
set_field :: JSObject a -> String -> a -> JSObject a
set_field (JSONObject [(String, a)]
xs) String
k a
v = [(String, a)] -> JSObject a
forall a. [(String, a)] -> JSObject a
JSONObject ((String
k,a
v) (String, a) -> [(String, a)] -> [(String, a)]
forall a. a -> [a] -> [a]
: ((String, a) -> Bool) -> [(String, a)] -> [(String, a)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
k) (String -> Bool) -> ((String, a) -> String) -> (String, a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, a) -> String
forall a b. (a, b) -> a
fst) [(String, a)]
xs)