module Composite.Aeson.Default where
import BasicPrelude
import Composite.Aeson.Base (JsonFormat(JsonFormat), JsonProfunctor(JsonProfunctor))
import Data.Aeson (FromJSON, ToJSON(toJSON))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.BetterErrors as ABE
import Data.Int (Int8, Int16)
import Data.Scientific (Scientific)
import qualified Data.Scientific as Scientific
import Data.Word (Word8, Word16)
class DefaultJsonFormat a where
defaultJsonFormat :: JsonFormat e a
instance DefaultJsonFormat Bool where defaultJsonFormat = boolJsonFormat
instance DefaultJsonFormat Char where defaultJsonFormat = charJsonFormat
instance DefaultJsonFormat Scientific where defaultJsonFormat = scientificJsonFormat
instance DefaultJsonFormat Float where defaultJsonFormat = realFloatJsonFormat
instance DefaultJsonFormat Double where defaultJsonFormat = realFloatJsonFormat
instance DefaultJsonFormat Int where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Int8 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Int16 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Int32 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Int64 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Word8 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Word16 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Word32 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat Word64 where defaultJsonFormat = integralJsonFormat
instance DefaultJsonFormat String where defaultJsonFormat = stringJsonFormat
instance DefaultJsonFormat Text where defaultJsonFormat = textJsonFormat
instance DefaultJsonFormat Aeson.Value where defaultJsonFormat = aesonValueJsonFormat
instance DefaultJsonFormat Aeson.Object where defaultJsonFormat = aesonObjectJsonFormat
instance DefaultJsonFormat Aeson.Array where defaultJsonFormat = aesonArrayJsonFormat
aesonJsonFormat :: (ToJSON a, FromJSON a) => JsonFormat e a
aesonJsonFormat = JsonFormat $ JsonProfunctor toJSON ABE.fromAesonParser
abeJsonFormat :: ToJSON a => ABE.Parse e a -> JsonFormat e a
abeJsonFormat p = JsonFormat $ JsonProfunctor toJSON p
boolJsonFormat :: JsonFormat e Bool
boolJsonFormat = abeJsonFormat ABE.asBool
charJsonFormat :: JsonFormat e Char
charJsonFormat = aesonJsonFormat
scientificJsonFormat :: JsonFormat e Scientific
scientificJsonFormat = abeJsonFormat ABE.asScientific
realFloatToJson :: RealFloat a => a -> Aeson.Value
realFloatToJson d
| isNaN d || isInfinite d = Aeson.Null
| otherwise = Aeson.Number $ Scientific.fromFloatDigits d
realFloatJsonFormat :: RealFloat a => JsonFormat e a
realFloatJsonFormat = JsonFormat $ JsonProfunctor realFloatToJson ABE.asRealFloat
integralJsonFormat :: Integral a => JsonFormat e a
integralJsonFormat = JsonFormat $ JsonProfunctor (Aeson.Number . fromIntegral) ABE.asIntegral
stringJsonFormat :: JsonFormat e String
stringJsonFormat = abeJsonFormat ABE.asString
textJsonFormat :: JsonFormat e Text
textJsonFormat = abeJsonFormat ABE.asText
nullJsonFormat :: JsonFormat e ()
nullJsonFormat = abeJsonFormat ABE.asNull
aesonValueJsonFormat :: JsonFormat e Aeson.Value
aesonValueJsonFormat = abeJsonFormat ABE.asValue
aesonObjectJsonFormat :: JsonFormat e Aeson.Object
aesonObjectJsonFormat = abeJsonFormat ABE.asObject
aesonArrayJsonFormat :: JsonFormat e Aeson.Array
aesonArrayJsonFormat = abeJsonFormat ABE.asArray