module Serokell.Data.Variant.Serialization
(
) where
import qualified Data.Aeson as Aeson
import Data.Bifunctor (bimap)
import qualified Data.HashMap.Strict as HM hiding (HashMap)
import Data.Scientific (floatingOrInteger)
import Serokell.Data.Variant.Variant (VarMap, Variant (..))
import Serokell.Util.Base64 (JsonByteString (JsonByteString))
import Serokell.Util.Text (show')
varMapToObject :: VarMap -> Aeson.Object
varMapToObject = HM.fromList . map (bimap show' Aeson.toJSON) . HM.toList
instance Aeson.ToJSON Variant where
toJSON VarNone = Aeson.Null
toJSON (VarBool v) = Aeson.toJSON v
toJSON (VarInt v) = Aeson.toJSON v
toJSON (VarUInt v) = Aeson.toJSON v
toJSON (VarFloat v) = Aeson.toJSON v
toJSON (VarBytes v) = Aeson.toJSON . JsonByteString $ v
toJSON (VarString v) = Aeson.toJSON v
toJSON (VarList v) = Aeson.toJSON v
toJSON (VarMap v) = Aeson.Object . varMapToObject $ v
toEncoding VarNone = Aeson.toEncoding Aeson.Null
toEncoding (VarBool v) = Aeson.toEncoding v
toEncoding (VarInt v) = Aeson.toEncoding v
toEncoding (VarUInt v) = Aeson.toEncoding v
toEncoding (VarFloat v) = Aeson.toEncoding v
toEncoding (VarBytes v) = Aeson.toEncoding . JsonByteString $ v
toEncoding (VarString v) = Aeson.toEncoding v
toEncoding (VarList v) = Aeson.toEncoding v
toEncoding (VarMap v) = Aeson.toEncoding . varMapToObject $ v
instance Aeson.FromJSON Variant where
parseJSON Aeson.Null = pure VarNone
parseJSON (Aeson.Bool v) = pure . VarBool $ v
parseJSON (Aeson.Number v) =
pure . either VarFloat convertInt . floatingOrInteger $ v
where
convertInt :: Integer -> Variant
convertInt i
| i < 0 = VarInt $ fromIntegral i
| otherwise = VarUInt $ fromIntegral i
parseJSON (Aeson.String v) = pure . VarString $ v
parseJSON (Aeson.Array v) = fmap VarList . mapM Aeson.parseJSON $ v
parseJSON (Aeson.Object v) =
fmap (VarMap . HM.fromList) .
mapM
(\(key,val) ->
(VarString key, ) <$> Aeson.parseJSON val) .
HM.toList $
v