{-# LANGUAGE DeriveDataTypeable #-}{-# LANGUAGE EmptyDataDecls #-}{-# LANGUAGE NoImplicitPrelude #-}{-# LANGUAGE OverloadedStrings #-}{-# LANGUAGE RankNTypes #-}moduleData.Aeson.Encoding.Internal(-- * EncodingEncoding' (..),Encoding ,encodingToLazyByteString ,unsafeToEncoding ,retagEncoding ,Series (..),pairs ,pair ,pairStr ,pair' -- * Predicates,nullEncoding -- * Encoding constructors,emptyArray_ ,emptyObject_ ,wrapObject ,wrapArray ,null_ ,bool ,text ,lazyText ,string ,list ,dict ,tuple ,(>*< ),InArray ,empty ,(>< ),econcat -- ** Decimal numbers,int8 ,int16 ,int32 ,int64 ,int ,word8 ,word16 ,word32 ,word64 ,word ,integer ,float ,double ,scientific -- ** Decimal numbers as Text,int8Text ,int16Text ,int32Text ,int64Text ,intText ,word8Text ,word16Text ,word32Text ,word64Text ,wordText ,integerText ,floatText ,doubleText ,scientificText -- ** Time,day ,localTime ,utcTime ,timeOfDay ,zonedTime -- ** value,value -- ** JSON tokens,comma ,colon ,openBracket ,closeBracket ,openCurly ,closeCurly )whereimportPrelude.CompatimportData.Aeson.Types.Internal (Value )importData.ByteString.Builder(Builder,char7,toLazyByteString)importData.IntimportData.Scientific(Scientific)importData.Semigroup(Semigroup((<>)))importData.Text(Text)importData.Time(Day,LocalTime,TimeOfDay,UTCTime,ZonedTime)importData.Typeable(Typeable)importData.WordimportqualifiedData.Aeson.Encoding.Builder asEBimportqualifiedData.ByteString.BuilderasBimportqualifiedData.ByteString.LazyasBSLimportqualifiedData.Text.LazyasLT-- | An encoding of a JSON value.---- @tag@ represents which kind of JSON the Encoding is encoding to,-- we reuse 'Text' and 'Value' as tags here.newtypeEncoding' tag =Encoding {fromEncoding ::Builder-- ^ Acquire the underlying bytestring builder.}deriving(Typeable)-- | Often used synonym for 'Encoding''.typeEncoding =Encoding' Value -- | Make Encoding from Builder.---- Use with care! You have to make sure that the passed Builder-- is a valid JSON Encoding!unsafeToEncoding::Builder->Encoding' a unsafeToEncoding =Encoding encodingToLazyByteString::Encoding' a ->BSL.ByteStringencodingToLazyByteString =toLazyByteString.fromEncoding{-# INLINEencodingToLazyByteString#-}retagEncoding::Encoding' a ->Encoding' b retagEncoding =Encoding .fromEncoding--------------------------------------------------------------------------------- Encoding instances-------------------------------------------------------------------------------instanceShow(Encoding' a )whereshow (Encoding e )=show(toLazyByteStringe )instanceEq(Encoding' a )whereEncoding a == Encoding b =toLazyByteStringa ==toLazyByteStringb instanceOrd(Encoding' a )wherecompare (Encoding a )(Encoding b )=compare(toLazyByteStringa )(toLazyByteStringb )-- | A series of values that, when encoded, should be separated by-- commas. Since 0.11.0.0, the '.=' operator is overloaded to create-- either @(Text, Value)@ or 'Series'. You can use Series when-- encoding directly to a bytestring builder as in the following-- example:---- > toEncoding (Person name age) = pairs ("name" .= name <> "age" .= age)dataSeries =Empty |Value (Encoding' Series )deriving(Typeable)pair::Text->Encoding ->Series pair name val =pair' (text name )val {-# INLINEpair#-}pairStr::String->Encoding ->Series pairStr name val =pair' (string name )val {-# INLINEpairStr#-}pair'::Encoding' Text->Encoding ->Series pair' name val =Value $retagEncoding $retagEncoding name >< colon >< val instanceSemigroupSeries whereEmpty <> a =a a <>Empty =a Value a <>Value b =Value (a >< comma >< b )instanceMonoidSeries wheremempty =Empty mappend =(<>)nullEncoding::Encoding' a ->BoolnullEncoding =BSL.null.toLazyByteString.fromEncodingemptyArray_::Encoding emptyArray_ =Encoding EB.emptyArray_ emptyObject_::Encoding emptyObject_ =Encoding EB.emptyObject_ wrapArray::Encoding' a ->Encoding wrapArray e =retagEncoding $openBracket >< e >< closeBracket wrapObject::Encoding' a ->Encoding wrapObject e =retagEncoding $openCurly >< e >< closeCurly null_::Encoding null_ =Encoding EB.null_ bool::Bool->Encoding bool True=Encoding "true"boolFalse=Encoding "false"-- | Encode a series of key/value pairs, separated by commas.pairs::Series ->Encoding pairs (Value v )=openCurly >< retagEncoding v >< closeCurly pairsEmpty =emptyObject_ {-# INLINEpairs#-}list::(a ->Encoding )->[a ]->Encoding list _[]=emptyArray_ listto' (x :xs )=openBracket >< to' x >< commas xs >< closeBracket wherecommas =foldr(\v vs ->comma >< to' v >< vs )empty {-# INLINElist#-}-- | Encode as JSON objectdict::(k ->Encoding' Text)-- ^ key encoding->(v ->Encoding )-- ^ value encoding->(foralla .(k ->v ->a ->a )->a ->m ->a )-- ^ @foldrWithKey@ - indexed fold->m -- ^ container->Encoding dict encodeKey encodeVal foldrWithKey =pairs .foldrWithKey go memptywherego k v c =Value (encodeKV k v )<>c encodeKV k v =retagEncoding (encodeKey k )>< colon >< retagEncoding (encodeVal v ){-# INLINEdict#-}-- | Type tag for tuples contents, see 'tuple'.dataInArray infixr6>*< -- | See 'tuple'.(>*<)::Encoding' a ->Encoding' b ->Encoding' InArray a >*< b =retagEncoding a >< comma >< retagEncoding b {-# INLINE(>*<)#-}empty::Encoding' a empty =Encoding memptyeconcat::[Encoding' a ]->Encoding' a econcat =foldr(>< )empty infixr6>< (><)::Encoding' a ->Encoding' a ->Encoding' a Encoding a >< Encoding b =Encoding (a <>b ){-# INLINE(><)#-}-- | Encode as a tuple.---- @-- toEncoding (X a b c) = tuple $-- toEncoding a >*<-- toEncoding b >*<-- toEncoding ctuple::Encoding' InArray ->Encoding tuple b =retagEncoding $openBracket >< b >< closeBracket {-# INLINEtuple#-}text::Text->Encoding' a text =Encoding .EB.text lazyText::LT.Text->Encoding' a lazyText t =Encoding $B.char7'"'<>LT.foldrChunks(\x xs ->EB.unquoted x <>xs )(B.char7'"')t string::String->Encoding' a string =Encoding .EB.string --------------------------------------------------------------------------------- chars-------------------------------------------------------------------------------comma,colon,openBracket,closeBracket,openCurly,closeCurly::Encoding' a comma =Encoding $char7','colon =Encoding $char7':'openBracket =Encoding $char7'['closeBracket =Encoding $char7']'openCurly =Encoding $char7'{'closeCurly =Encoding $char7'}'--------------------------------------------------------------------------------- Decimal numbers-------------------------------------------------------------------------------int8::Int8->Encoding int8 =Encoding .B.int8Decint16::Int16->Encoding int16 =Encoding .B.int16Decint32::Int32->Encoding int32 =Encoding .B.int32Decint64::Int64->Encoding int64 =Encoding .B.int64Decint::Int->Encoding int =Encoding .B.intDecword8::Word8->Encoding word8 =Encoding .B.word8Decword16::Word16->Encoding word16 =Encoding .B.word16Decword32::Word32->Encoding word32 =Encoding .B.word32Decword64::Word64->Encoding word64 =Encoding .B.word64Decword::Word->Encoding word =Encoding .B.wordDecinteger::Integer->Encoding integer =Encoding .B.integerDecfloat::Float->Encoding float =realFloatToEncoding $Encoding .B.floatDecdouble::Double->Encoding double =realFloatToEncoding $Encoding .B.doubleDecscientific::Scientific->Encoding scientific =Encoding .EB.scientific realFloatToEncoding::RealFloata =>(a ->Encoding )->a ->Encoding realFloatToEncoding e d |isNaNd ||isInfinited =null_ |otherwise=e d {-# INLINErealFloatToEncoding#-}--------------------------------------------------------------------------------- Decimal numbers as Text-------------------------------------------------------------------------------int8Text::Int8->Encoding' a int8Text =Encoding .EB.quote .B.int8Decint16Text::Int16->Encoding' a int16Text =Encoding .EB.quote .B.int16Decint32Text::Int32->Encoding' a int32Text =Encoding .EB.quote .B.int32Decint64Text::Int64->Encoding' a int64Text =Encoding .EB.quote .B.int64DecintText::Int->Encoding' a intText =Encoding .EB.quote .B.intDecword8Text::Word8->Encoding' a word8Text =Encoding .EB.quote .B.word8Decword16Text::Word16->Encoding' a word16Text =Encoding .EB.quote .B.word16Decword32Text::Word32->Encoding' a word32Text =Encoding .EB.quote .B.word32Decword64Text::Word64->Encoding' a word64Text =Encoding .EB.quote .B.word64DecwordText::Word->Encoding' a wordText =Encoding .EB.quote .B.wordDecintegerText::Integer->Encoding' a integerText =Encoding .EB.quote .B.integerDecfloatText::Float->Encoding' a floatText =Encoding .EB.quote .B.floatDecdoubleText::Double->Encoding' a doubleText =Encoding .EB.quote .B.doubleDecscientificText::Scientific->Encoding' a scientificText =Encoding .EB.quote .EB.scientific --------------------------------------------------------------------------------- time-------------------------------------------------------------------------------day::Day->Encoding' a day =Encoding .EB.quote .EB.day localTime::LocalTime->Encoding' a localTime =Encoding .EB.quote .EB.localTime utcTime::UTCTime->Encoding' a utcTime =Encoding .EB.quote .EB.utcTime timeOfDay::TimeOfDay->Encoding' a timeOfDay =Encoding .EB.quote .EB.timeOfDay zonedTime::ZonedTime->Encoding' a zonedTime =Encoding .EB.quote .EB.zonedTime --------------------------------------------------------------------------------- Value-------------------------------------------------------------------------------value::Value ->Encoding value =Encoding .EB.encodeToBuilder