{-# LANGUAGE BangPatterns #-}{-# LANGUAGE OverloadedStrings #-}-- |-- Module: Data.Aeson.Text-- Copyright: (c) 2012-2016 Bryan O'Sullivan-- (c) 2011 MailRank, Inc.-- License: BSD3-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>-- Stability: experimental-- Portability: portable---- Most frequently, you'll probably want to encode straight to UTF-8-- (the standard JSON encoding) using 'encode'.---- You can use the conversions to 'Builder's when embedding JSON messages as-- parts of a protocol.moduleData.Aeson.Text(encodeToLazyText ,encodeToTextBuilder )whereimportPrelude()importPrelude.CompatimportData.Aeson.Types (Value (..),ToJSON (..))importData.Aeson.Encoding (encodingToLazyByteString )importData.Monoid((<>))importData.Scientific(FPFormat(..),Scientific,base10Exponent)importData.Text.Lazy.BuilderimportData.Text.Lazy.Builder.Scientific(formatScientificBuilder)importNumeric(showHex)importqualifiedData.HashMap.StrictasHimportqualifiedData.TextasTimportqualifiedData.Text.LazyasLTimportqualifiedData.Text.Lazy.EncodingasLTimportqualifiedData.VectorasV-- | Encode a JSON 'Value' to a "Data.Text.Lazy"---- /Note:/ uses 'toEncoding'encodeToLazyText::ToJSON a =>a ->LT.TextencodeToLazyText =LT.decodeUtf8.encodingToLazyByteString .toEncoding -- | Encode a JSON 'Value' to a "Data.Text" 'Builder', which can be-- embedded efficiently in a text-based protocol.---- If you are going to immediately encode straight to a-- 'L.ByteString', it is more efficient to use 'encodeToBuilder'-- instead.---- /Note:/ Uses 'toJSON'encodeToTextBuilder::ToJSON a =>a ->BuilderencodeToTextBuilder =go .toJSON wherego Null ={-# SCC "go/Null" #-}"null"go(Bool b )={-# SCC "go/Bool" #-}ifb then"true"else"false"go(Number s )={-# SCC "go/Number" #-}fromScientific s go(String s )={-# SCC "go/String" #-}string s go(Array v )|V.nullv ={-# SCC "go/Array" #-}"[]"|otherwise={-# SCC "go/Array" #-}singleton'['<>go (V.unsafeHeadv )<>V.foldrf (singleton']')(V.unsafeTailv )wheref a z =singleton','<>go a <>z go(Object m )={-# SCC "go/Object" #-}caseH.toListm of(x :xs )->singleton'{'<>one x <>foldrf (singleton'}')xs _->"{}"wheref a z =singleton','<>one a <>z one (k ,v )=string k <>singleton':'<>go v string::T.Text->Builderstring s ={-# SCC "string" #-}singleton'"'<>quote s <>singleton'"'wherequote q =caseT.unconst ofNothing->fromTexth Just(!c ,t' )->fromTexth <>escape c <>quote t' where(h ,t )={-# SCC "break" #-}T.breakisEscape q isEscape c =c =='\"'||c =='\\'||c <'\x20'escape '\"'="\\\""escape'\\'="\\\\"escape'\n'="\\n"escape'\r'="\\r"escape'\t'="\\t"escapec |c <'\x20'=fromString$"\\u"++replicate(4-lengthh )'0'++h |otherwise=singletonc whereh =showHex(fromEnumc )""fromScientific::Scientific->BuilderfromScientific s =formatScientificBuilderformat prec s where(format ,prec )|base10Exponents <0=(Generic,Nothing)|otherwise=(Fixed,Just0)