{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} -- | Variant type. module Serokell.Data.Variant.Variant ( Variant (..) , VarList , VarMap ) where import Control.DeepSeq (NFData) import Data.ByteString (ByteString) import Data.Hashable (Hashable (hashWithSalt)) import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HM hiding (HashMap) import Data.Int (Int64) import Data.String (IsString (fromString)) import Data.Text (Text) import Data.Text.Buildable (Buildable (build)) import Data.Vector (Vector) import qualified Data.Vector as V hiding (Vector) import Data.Word (Word64) import GHC.Exts (IsList (..)) import GHC.Generics (Generic) import qualified Serokell.Util.Base16 as B16 import Serokell.Util.Text (listBuilderJSONIndent, mapBuilder) type VarList = Vector Variant type VarMap = HashMap Variant Variant -- | Variant is intended to store arbitrary data in arbitrary -- format. You are free to choose data layout. data Variant = VarNone -- ^ None, i. e. no value. | VarBool !Bool -- ^ Boolean value. | VarInt !Int64 -- ^ Signed integer number. | VarUInt !Word64 -- ^ Unsigned integer number. | VarFloat !Double -- ^ IEEE 754 double precision floating point number. | VarBytes !ByteString -- ^ Raw bytes. | VarString !Text -- ^ Unicode string. | VarList !VarList -- ^ List of Variants. | VarMap !VarMap -- ^ Map (with unique keys) from Variant to Variant. deriving (Show,Eq,Generic) instance Buildable Variant where build VarNone = "None" build (VarBool v) = build v build (VarInt v) = build v build (VarUInt v) = build v build (VarFloat v) = build v build (VarBytes v) = build . B16.encode $ v build (VarString v) = build v build (VarList v) = listBuilderJSONIndent 2 v build (VarMap v) = mapBuilder . HM.toList $ v instance Hashable (Vector Variant) where hashWithSalt salt = V.foldr' (flip hashWithSalt) (hashWithSalt salt ()) instance Hashable Variant instance IsString Variant where fromString = VarString . fromString instance IsList Variant where type Item Variant = Variant toList (VarList v) = toList v toList _ = error "toList: not a list" fromList = VarList . fromList instance NFData Variant