thrift/lib/hs/Thrift/Protocol/PrettyJSON.hs (93 lines of code) (raw):

-- -- Licensed to the Apache Software Foundation (ASF) under one -- or more contributor license agreements. See the NOTICE file -- distributed with this work for additional information -- regarding copyright ownership. The ASF licenses this file -- to you under the Apache License, Version 2.0 (the -- "License"); you may not use this file except in compliance -- with the License. You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, -- software distributed under the License is distributed on an -- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -- KIND, either express or implied. See the License for the -- specific language governing permissions and limitations -- under the License. -- {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} module Thrift.Protocol.PrettyJSON ( module Thrift.Protocol , PrettyJSONProtocol(..) ) where import Data.ByteString.Builder as B import Data.Int import Data.List #if __GLASGOW_HASKELL__ < 804 import Data.Monoid #endif import Data.Text.Lazy.Encoding import qualified Data.HashMap.Strict as Map import qualified Data.Text.Lazy as LT import Thrift.Protocol import Thrift.Protocol.JSONUtils import Thrift.Protocol.SimpleJSON import Thrift.Types -- | The Pretty JSON Protocol data uses the standard 'TSimpleJSONProtocol' -- for parsing and serializes as pretty printed JSON. -- Data is encoded as a JSON 'ByteString' data PrettyJSONProtocol t = PrettyJSONProtocol Int t -- ^ Construct a 'JSONProtocol' with an indent width -- and a 'Transport' instance Protocol PrettyJSONProtocol where mkProtocol = PrettyJSONProtocol 3 getTransport (PrettyJSONProtocol _ t) = t writeMessage (PrettyJSONProtocol _ t) = writeMessage (SimpleJSONProtocol t) readMessage (PrettyJSONProtocol _ t) = readMessage (SimpleJSONProtocol t) serializeVal (PrettyJSONProtocol indent _) = toLazyByteString . buildJSONValue indent 0 deserializeVal (PrettyJSONProtocol _ t) = deserializeVal (SimpleJSONProtocol t) readVal (PrettyJSONProtocol _ t) = readVal (SimpleJSONProtocol t) -- Writing Functions indented :: Int -> Builder indented i = mconcat $ "\n" : replicate i " " buildJSONValue :: Int -> Int -> ThriftVal -> Builder buildJSONValue i l (TStruct fields) = "{" <> indented (l + i) <> buildJSONStruct i (l + i) fields <> indented l <> "}" buildJSONValue i l (TMap _ _ entries) = "{" <> indented (l + i) <> buildJSONMap i (l + i) entries <> indented l <> "}" buildJSONValue i l (TList _ entries) = "[" <> indented (l + i) <> buildJSONList i (l + i) entries <> indented l <> "]" buildJSONValue i l (TSet _ entries) = "[" <> indented (l + i) <> buildJSONList i (l + i) entries <> indented l <> "]" buildJSONValue _ _ (TBool b) = if b then "true" else "false" buildJSONValue _ _ (TByte b) = int8Dec b buildJSONValue _ _ (TI16 i) = int16Dec i buildJSONValue _ _ (TI32 i) = int32Dec i buildJSONValue _ _ (TI64 i) = int64Dec i buildJSONValue _ _ (TFloat f) = floatDec f buildJSONValue _ _ (TDouble d) = doubleDec d buildJSONValue _ _ (TString s) = "\"" <> escape s <> "\"" buildJSONStruct :: Int -> Int -> Map.HashMap Int16 (LT.Text, ThriftVal) -> Builder buildJSONStruct i l = mconcat . intersperse ("," <> indented l) . Map.elems . Map.map (\(str,val) -> "\"" <> B.lazyByteString (encodeUtf8 str) <> "\": " <> buildJSONValue i l val) buildJSONMap :: Int -> Int -> [(ThriftVal, ThriftVal)] -> Builder buildJSONMap i l = mconcat . intersperse ("," <> indented l) . map buildKV where buildKV (key@(TString _), val) = buildJSONValue i l key <> ": " <> buildJSONValue i l val buildKV (key, val) = "\"" <> buildJSONValue i l key <> "\": " <> buildJSONValue i l val buildJSONList :: Int -> Int -> [ThriftVal] -> Builder buildJSONList i l = mconcat . intersperse ("," <> indented l) . map (buildJSONValue i l)