summaryrefslogtreecommitdiff
path: root/Utility
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2016-07-26 21:43:05 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2016-07-26 21:43:05 -0400
commit13295d61d5c8aad8761b7ea54f741e498ffdf872 (patch)
tree494938a8282a1935bb678f7deea29ea9dd74961c /Utility
parent9d840b6f9cda6c5299bcb246d3d9675cb680d69a (diff)
avoid using Strings for JSON output; keep it ByteString throughout
Diffstat (limited to 'Utility')
-rw-r--r--Utility/JSONStream.hs42
1 files changed, 25 insertions, 17 deletions
diff --git a/Utility/JSONStream.hs b/Utility/JSONStream.hs
index af321b2f9..c5d4e1c8d 100644
--- a/Utility/JSONStream.hs
+++ b/Utility/JSONStream.hs
@@ -16,7 +16,9 @@ module Utility.JSONStream (
import Data.Aeson
import qualified Data.Text as T
-import qualified Data.ByteString.Lazy.UTF8 as B
+import qualified Data.ByteString.Lazy as B
+import Data.Char
+import Data.Word
data JSONChunk v where
JSONChunk :: ToJSON v => [(String, v)] -> JSONChunk [(String, v)]
@@ -32,29 +34,35 @@ encodeJSONChunk (AesonObject o) = encode o
- with streaming output. To support streaming, a hack:
- The final "}" is left off the JSON, allowing more chunks to be added
- to later. -}
-start :: JSONChunk a -> String
+start :: JSONChunk a -> B.ByteString
start a
- | last s == endchar = init s
- | otherwise = bad s
+ | not (B.null b) && B.last b == endchar = B.init b
+ | otherwise = bad b
where
- s = B.toString $ encodeJSONChunk a
+ b = encodeJSONChunk a
-add :: JSONChunk a -> String
+add :: JSONChunk a -> B.ByteString
add a
- | head s == startchar = ',' : drop 1 s
- | otherwise = bad s
+ | not (B.null b) && B.head b == startchar = B.cons addchar (B.drop 1 b)
+ | otherwise = bad b
where
- s = start a
+ b = start a
-end :: String
-end = [endchar, '\n']
+end :: B.ByteString
+end = endchar `B.cons` sepchar `B.cons` B.empty
-startchar :: Char
-startchar = '{'
+startchar :: Word8
+startchar = fromIntegral (ord '{')
-endchar :: Char
-endchar = '}'
+endchar :: Word8
+endchar = fromIntegral (ord '}')
-bad :: String -> a
-bad s = error $ "JSON encoder generated unexpected value: " ++ s
+addchar :: Word8
+addchar = fromIntegral (ord ',')
+
+sepchar :: Word8
+sepchar = fromIntegral (ord '\n')
+
+bad :: B.ByteString -> a
+bad b = error $ "JSON encoder generated unexpected value: " ++ show b