module Tendermint.Utils.Events where
import Control.Error (fmapL)
import qualified Data.Aeson as A
import qualified Data.ByteArray.Base64String as Base64
import qualified Data.ByteString as BS
import Data.Proxy
import Data.String.Conversions (cs)
import Data.Text (Text)
import GHC.Exts (fromList)
import Network.ABCI.Types.Messages.FieldTypes (Event (..),
KVPair (..))
import Tendermint.SDK.BaseApp.Events (ToEvent, makeEventType)
class ToEvent e => FromEvent e where
fromEvent :: Event -> Either Text e
default fromEvent :: A.FromJSON e => Event -> Either Text e
fromEvent Event{eventType, eventAttributes} =
let expectedType = makeEventType (Proxy @e)
in if cs eventType /= expectedType
then fail ("Couldn't match expected event type " <> expectedType <>
" with found type " <> cs eventType)
else
let fromKVPair :: KVPair -> Either String (Text, A.Value)
fromKVPair (KVPair k v) = do
value <- A.eitherDecode . cs @BS.ByteString . Base64.toBytes $ v
return (cs @BS.ByteString . Base64.toBytes $ k, value)
in fmapL cs $ do
kvPairs <- traverse fromKVPair eventAttributes
A.eitherDecode . A.encode . A.Object . fromList $ kvPairs