{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE ImportQualifiedPost #-} module Haskoin.Util.Marshal where import Control.Monad import Crypto.Secp256k1 import Data.Aeson import Data.Aeson.Encoding import Data.Aeson.Types import Data.ByteString import Data.ByteString.Builder import Data.ByteString.Lazy qualified as Lazy import Data.Bytes.Get import Data.Bytes.Put import Data.Bytes.Serial class Marshal s a | a -> s where marshalPut :: (MonadPut m) => s -> a -> m () marshalGet :: (MonadGet m) => s -> m a marshal :: (Marshal s a) => s -> a -> ByteString marshal s = runPutS . marshalPut s marshalLazy :: (Marshal s a) => s -> a -> Lazy.ByteString marshalLazy s = runPutL . marshalPut s unmarshal :: (Marshal s a) => s -> ByteString -> Either String a unmarshal = runGetS . marshalGet unmarshalLazy :: (Marshal s a) => s -> Lazy.ByteString -> a unmarshalLazy = runGetL . marshalGet class MarshalJSON s a | a -> s where marshalValue :: s -> a -> Value marshalEncoding :: s -> a -> Encoding marshalEncoding x = value . marshalValue x unmarshalValue :: s -> Value -> Parser a marshalJSON :: (MarshalJSON s a) => s -> a -> Lazy.ByteString marshalJSON s = toLazyByteString . fromEncoding . marshalEncoding s unmarshalJSON :: (MarshalJSON s a) => s -> Lazy.ByteString -> Maybe a unmarshalJSON s = parseMaybe (unmarshalValue s) <=< decode