1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
{-# LANGUAGE DeriveDataTypeable #-}
-- | Basic support for working with JSON values.
module Text.JSON.Types (
-- * JSON Types
JSValue(..)
-- * Wrapper Types
, JSString({-fromJSString-}..)
, toJSString
, JSObject({-fromJSObject-}..)
, toJSObject
, get_field
, set_field
) where
import Data.Typeable ( Typeable )
import Data.String(IsString(..))
--
-- | JSON values
--
-- The type to which we encode Haskell values. There's a set
-- of primitives, and a couple of heterogenous collection types.
--
-- Objects:
--
-- An object structure is represented as a pair of curly brackets
-- surrounding zero or more name\/value pairs (or members). A name is a
-- string. A single colon comes after each name, separating the name
-- from the value. A single comma separates a value from a
-- following name.
--
-- Arrays:
--
-- An array structure is represented as square brackets surrounding
-- zero or more values (or elements). Elements are separated by commas.
--
-- Only valid JSON can be constructed this way
--
data JSValue
= JSNull
| JSBool !Bool
| JSRational Bool{-as Float?-} !Rational
| JSString JSString
| JSArray [JSValue]
| JSObject (JSObject JSValue)
deriving (Show, Read, Eq, Ord, Typeable)
-- | Strings can be represented a little more efficiently in JSON
newtype JSString = JSONString { fromJSString :: String }
deriving (Eq, Ord, Show, Read, Typeable)
-- | Turn a Haskell string into a JSON string.
toJSString :: String -> JSString
toJSString = JSONString
-- Note: we don't encode the string yet, that's done when serializing.
instance IsString JSString where
fromString = toJSString
instance IsString JSValue where
fromString = JSString . fromString
-- | As can association lists
newtype JSObject e = JSONObject { fromJSObject :: [(String, e)] }
deriving (Eq, Ord, Show, Read, Typeable )
-- | Make JSON object out of an association list.
toJSObject :: [(String,a)] -> JSObject a
toJSObject = JSONObject
-- | Get the value of a field, if it exist.
get_field :: JSObject a -> String -> Maybe a
get_field (JSONObject xs) x = lookup x xs
-- | Set the value of a field. Previous values are overwritten.
set_field :: JSObject a -> String -> a -> JSObject a
set_field (JSONObject xs) k v = JSONObject ((k,v) : filter ((/= k).fst) xs)
|