on 0.3.2.12 help sign in
70 lines 2.7 kB history raw
1{-# LANGUAGE OverloadedStrings #-}
3-- Simplest example of parsing and encoding JSON with Aeson.
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.
10import Data.Aeson
11import qualified Data.Aeson.Types as T
13import Data.Attoparsec (parse, Result(..))
14import Data.Text (Text)
15import Control.Applicative ((<$>))
16import Control.Monad (mzero)
17import qualified Data.ByteString.Char8 as BS
18-- Aeson's "encode" to JSON generates lazy bytestrings
19import qualified Data.ByteString.Lazy.Char8 as BSL
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.
23main ::IO ()
24main = do
25 print $ parseMsgFromString exampleJSONMessage
26 let reply = Msg "hello Aeson!"
27 putStrLn $ "Encoded reply: " ++ BSL.unpack (encode reply)
29-- this is the type we'll be converting to and from JSON
30data Msg = Msg Text deriving (Show)
32-- here's how we should parse JSON and construct a Msg
33instance FromJSON Msg where
34 parseJSON (Object v) = Msg <$> v .: "message"
35 parseJSON _ = mzero
37-- here's how we should encode a Msg as JSON
38instance ToJSON Msg where
39 toJSON (Msg s) = object [ "message" .= s]
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.
58parseMsgFromString :: String -> Maybe Msg
59parseMsgFromString 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
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.
69exampleJSONMessage :: String
70exampleJSONMessage = "{\"message\":\"hello world\"}"