on master help sign in
Merge Neill Bogie's changes
7bf28ddBryan O'Sullivan
Data/Aeson/Types.hs+4
@@ -289,6 +289,8 @@ object = Object . M.fromList
289-- instance ToJSON Coord where
289-- instance ToJSON Coord where
290-- toJSON (Coord x y) = 'object' [\"x\" '.=' x, \"y\" '.=' y]
290-- toJSON (Coord x y) = 'object' [\"x\" '.=' x, \"y\" '.=' y]
291-- @
291-- @
292+--
293+-- This example assumes the OverloadedStrings language option is enabled.
292class ToJSON a where
294class ToJSON a where
293 toJSON :: a -> Value
295 toJSON :: a -> Value
294
296
@@ -311,6 +313,8 @@ class ToJSON a where
311-- \-- A non-'Object' value is of the wrong type, so use 'mzero' to fail.
313-- \-- A non-'Object' value is of the wrong type, so use 'mzero' to fail.
312-- parseJSON _ = 'mzero'
314-- parseJSON _ = 'mzero'
313-- @
315-- @
316+--
317+-- This example assumes the OverloadedStrings language option is enabled.
314class FromJSON a where
318class FromJSON a where
315 parseJSON :: Value -> Parser a
319 parseJSON :: Value -> Parser a
316
320
aeson.cabal+1
@@ -96,6 +96,7 @@ extra-source-files:
96 benchmarks/json-data/twitter100.json
96 benchmarks/json-data/twitter100.json
97 tests/Makefile
97 tests/Makefile
98 tests/Properties.hs
98 tests/Properties.hs
99+ examples/Demo.hs
99
100
100flag developer
101flag developer
101 description: operate in developer mode
102 description: operate in developer mode
examples/Demo.hsnew file+70
@@ -0,0 +1,70 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+-- Simplest example of parsing and encoding JSON with Aeson.
4+
5+-- Above, we enable OverloadedStrings to allow a literal string (e.g. "name")
6+-- to be automatically converted to Data.Text.
7+-- This is useful when using Aeson's functions such as (.:) which expect Text.
8+-- Without it we'd need to use pack.
9+
10+import Data.Aeson
11+import qualified Data.Aeson.Types as T
12+
13+import Data.Attoparsec (parse, Result(..))
14+import Data.Text (Text)
15+import Control.Applicative ((<$>))
16+import Control.Monad (mzero)
17+import qualified Data.ByteString.Char8 as BS
18+-- Aeson's "encode" to JSON generates lazy bytestrings
19+import qualified Data.ByteString.Lazy.Char8 as BSL
20+
21+-- In main we'll parse a JSON message into a Msg and display that,
22+-- then we'll encode a different Msg as JSON, and display it.
23+main ::IO ()
24+main = do
25+ print $ parseMsgFromString exampleJSONMessage
26+ let reply = Msg "hello Aeson!"
27+ putStrLn $ "Encoded reply: " ++ BSL.unpack (encode reply)
28+
29+-- this is the type we'll be converting to and from JSON
30+data Msg = Msg Text deriving (Show)
31+
32+-- here's how we should parse JSON and construct a Msg
33+instance FromJSON Msg where
34+ parseJSON (Object v) = Msg <$> v .: "message"
35+ parseJSON _ = mzero
36+
37+-- here's how we should encode a Msg as JSON
38+instance ToJSON Msg where
39+ toJSON (Msg s) = object [ "message" .= s]
40+
41+-- Here's one way to actually run the parsers.
42+--
43+-- Note that we do two parses:
44+-- once into JSON then one more into our final type.
45+-- There are a number of choices when dealing with parse failures.
46+-- Here we've chosen to parse to Maybe Msg, and a Nothing will be returned
47+-- if parseJSON fails. (More informative options are available.)
48+--
49+-- This should take us (depending on success or failure)
50+-- from {"message": "hello world"} to Just (Msg "hello world")
51+-- or to Nothing
52+--
53+-- Note also that we have not checked here that the input has been completely
54+-- consumed, so:
55+-- {"message": "hello world"} foo BIG mistake
56+-- would yield the same successfully translated message!
57+-- We could look in "rest" for the remainder.
58+parseMsgFromString :: String -> Maybe Msg
59+parseMsgFromString s =
60+ let bs = BS.pack s
61+ in case parse json bs of
62+ (Done rest r) -> T.parseMaybe parseJSON r :: Maybe Msg
63+ _ -> Nothing
64+
65+-- Here's the example JSON message we're going to try to parse:
66+-- {"message": "hello world"}
67+-- It's a JSON object with a single pair, having key 'message', and a string value.
68+-- It could have more fields and structure, but that's all we're going to parse out of it.
69+exampleJSONMessage :: String
70+exampleJSONMessage = "{\"message\":\"hello world\"}"
examples/Simplest.hsnew file+33
@@ -0,0 +1,33 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+import Control.Applicative ((<$>), (<*>))
4+import Control.Monad (mzero)
5+import Data.Aeson
6+import qualified Data.Aeson.Types as T
7+import Data.Attoparsec (parse, Result(..))
8+import qualified Data.ByteString.Char8 as BS
9+import qualified Data.ByteString.Lazy.Char8 as BSL
10+
11+main ::IO ()
12+main = do
13+ print $ parseFromString "{\"x\":3.0,\"y\":-1.0}"
14+ let reply = Coord 123.4 20
15+ putStrLn $ BSL.unpack (encode reply)
16+
17+data Coord = Coord { x :: Double, y :: Double } deriving (Show)
18+
19+instance ToJSON Coord where
20+ toJSON (Coord xV yV) = object ["x" .= xV, "y" .= yV]
21+
22+instance FromJSON Coord where
23+ parseJSON (Object v) = Coord <$>
24+ v .: "x" <*>
25+ v .: "y"
26+ parseJSON _ = mzero
27+
28+parseFromString :: String -> Maybe Coord
29+parseFromString s =
30+ let bs = BS.pack s
31+ in case parse json bs of
32+ Done _rest res -> T.parseMaybe parseJSON res
33+ _ -> Nothing