on master help sign in
Support JSON encoding
commit9783a48c9129a6433576d6890cabae47ebb23e2f authorBryan O'Sullivan <bos@mailrank.com> dateFri 21 Jan 2011, 15:06 (16 years ago) parent4e92fd1
2 files changed+57
Data/Aeson/Encode.hs+55 aeson.cabal+2
Data/Aeson/Encode.hsnew file+55
@@ -0,0 +1,55 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Data.Aeson.Encode
4+ (
5+ build
6+ , encode
7+ ) where
8+
9+import Blaze.ByteString.Builder
10+import Blaze.ByteString.Builder.Char.Utf8
11+import Data.Aeson.Types (JSON(..), Value(..))
12+import Data.Monoid (mappend, mconcat)
13+import qualified Data.ByteString.Char8 as B
14+import qualified Data.ByteString.Lazy.Char8 as L
15+import qualified Data.Map as M
16+import qualified Data.Text as T
17+import qualified Data.Vector as V
18+
19+build :: Value -> Builder
20+build Null = fromByteString "null"
21+build (Bool b) = fromByteString $ if b then "true" else "false"
22+build (Number n) = fromByteString (B.pack (show n))
23+build (String s) = string s
24+build (Array v)
25+ | V.null v = fromByteString "[]"
26+ | otherwise = fromChar '[' `mappend`
27+ build (V.unsafeHead v) `mappend`
28+ V.foldr f (fromChar ']') (V.unsafeTail v)
29+ where f a z = fromChar ',' `mappend` build a `mappend` z
30+build (Object m) =
31+ case M.toList m of
32+ (x:xs) -> fromChar '{' `mappend`
33+ one x `mappend`
34+ foldr f (fromChar '}') xs
35+ _ -> fromByteString "{}"
36+ where f a z = fromChar ',' `mappend` one a `mappend` z
37+ one (k,v) = string k `mappend` fromChar ':' `mappend` build v
38+
39+string :: T.Text -> Builder
40+string s = fromChar '"' `mappend` quote s `mappend` fromChar '"'
41+ where
42+ quote s = case T.uncons t of
43+ Just (c,t') -> mconcat [fromText h, fromText (escape c),
44+ quote t']
45+ Nothing -> fromText h
46+ where (h,t) = T.break isEscape s
47+ isEscape c = c == '\"' || c == '\n' || c == '\r' || c == '\t'
48+ escape '\"' = "\\\""
49+ escape '\n' = "\\n"
50+ escape '\r' = "\\r"
51+ escape '\t' = "\\t"
52+
53+encode :: JSON a => a -> L.ByteString
54+encode = toLazyByteString . build . toJSON
55+{-# INLINE encode #-}
aeson.cabal+2
@@ -25,6 +25,7 @@ flag developer
2525library
2626 exposed-modules:
2727 Data.Aeson
28+ Data.Aeson.Encode
2829 Data.Aeson.Parser
2930 Data.Aeson.Parser.Internal
3031 Data.Aeson.Types
@@ -32,6 +33,7 @@ library
3233 build-depends:
3334 attoparsec >= 0.8.4.0,
3435 base == 4.*,
36+ blaze-builder >= 0.2.1.4,
3537 bytestring,
3638 containers == 0.3.*,
3739 old-locale,