module Tendermint.SDK.Codec
( HasCodec(..)
, defaultSDKAesonOptions
) where
import Data.Aeson (Options)
import Data.Aeson.Casing (aesonDrop, snakeCase)
import Data.Bifunctor (first)
import qualified Data.ByteString as BS
import Data.Int (Int32, Int64)
import qualified Data.ProtoLens.Encoding.Bytes as PB
import Data.String.Conversions (cs)
import Data.Text (Text)
import Data.Word (Word32, Word64)
class HasCodec a where
encode :: a -> BS.ByteString
decode :: BS.ByteString -> Either Text a
instance HasCodec () where
encode :: () -> ByteString
encode = ByteString -> () -> ByteString
forall a b. a -> b -> a
const ""
decode :: ByteString -> Either Text ()
decode = Either Text () -> ByteString -> Either Text ()
forall a b. a -> b -> a
const (Either Text () -> ByteString -> Either Text ())
-> Either Text () -> ByteString -> Either Text ()
forall a b. (a -> b) -> a -> b
$ () -> Either Text ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
instance HasCodec Word32 where
encode :: Word32 -> ByteString
encode = Builder -> ByteString
PB.runBuilder (Builder -> ByteString)
-> (Word32 -> Builder) -> Word32 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Builder
PB.putFixed32
decode :: ByteString -> Either Text Word32
decode = (String -> Text) -> Either String Word32 -> Either Text Word32
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (Either String Word32 -> Either Text Word32)
-> (ByteString -> Either String Word32)
-> ByteString
-> Either Text Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser Word32 -> ByteString -> Either String Word32
forall a. Parser a -> ByteString -> Either String a
PB.runParser Parser Word32
PB.getFixed32
instance HasCodec Int32 where
encode :: Int32 -> ByteString
encode = Builder -> ByteString
PB.runBuilder (Builder -> ByteString)
-> (Int32 -> Builder) -> Int32 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Builder
PB.putFixed32 (Word32 -> Builder) -> (Int32 -> Word32) -> Int32 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Word32
PB.signedInt32ToWord
decode :: ByteString -> Either Text Int32
decode = (String -> Text) -> Either String Int32 -> Either Text Int32
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (Either String Int32 -> Either Text Int32)
-> (ByteString -> Either String Int32)
-> ByteString
-> Either Text Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser Int32 -> ByteString -> Either String Int32
forall a. Parser a -> ByteString -> Either String a
PB.runParser (Word32 -> Int32
PB.wordToSignedInt32 (Word32 -> Int32) -> Parser Word32 -> Parser Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word32
PB.getFixed32)
instance HasCodec Word64 where
encode :: Word64 -> ByteString
encode = Builder -> ByteString
PB.runBuilder (Builder -> ByteString)
-> (Word64 -> Builder) -> Word64 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Builder
PB.putFixed64
decode :: ByteString -> Either Text Word64
decode = (String -> Text) -> Either String Word64 -> Either Text Word64
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (Either String Word64 -> Either Text Word64)
-> (ByteString -> Either String Word64)
-> ByteString
-> Either Text Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser Word64 -> ByteString -> Either String Word64
forall a. Parser a -> ByteString -> Either String a
PB.runParser Parser Word64
PB.getFixed64
instance HasCodec Int64 where
encode :: Int64 -> ByteString
encode = Builder -> ByteString
PB.runBuilder (Builder -> ByteString)
-> (Int64 -> Builder) -> Int64 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Builder
PB.putFixed64 (Word64 -> Builder) -> (Int64 -> Word64) -> Int64 -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> Word64
PB.signedInt64ToWord
decode :: ByteString -> Either Text Int64
decode = (String -> Text) -> Either String Int64 -> Either Text Int64
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (Either String Int64 -> Either Text Int64)
-> (ByteString -> Either String Int64)
-> ByteString
-> Either Text Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser Int64 -> ByteString -> Either String Int64
forall a. Parser a -> ByteString -> Either String a
PB.runParser (Word64 -> Int64
PB.wordToSignedInt64 (Word64 -> Int64) -> Parser Word64 -> Parser Int64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Word64
PB.getFixed64)
instance HasCodec String where
encode :: String -> ByteString
encode = String -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs
decode :: ByteString -> Either Text String
decode = String -> Either Text String
forall a b. b -> Either a b
Right (String -> Either Text String)
-> (ByteString -> String) -> ByteString -> Either Text String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
forall a b. ConvertibleStrings a b => a -> b
cs
instance HasCodec Text where
encode :: Text -> ByteString
encode = Text -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs
decode :: ByteString -> Either Text Text
decode = Text -> Either Text Text
forall a b. b -> Either a b
Right (Text -> Either Text Text)
-> (ByteString -> Text) -> ByteString -> Either Text Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
forall a b. ConvertibleStrings a b => a -> b
cs
instance HasCodec BS.ByteString where
encode :: ByteString -> ByteString
encode = ByteString -> ByteString
forall a. a -> a
id
decode :: ByteString -> Either Text ByteString
decode = ByteString -> Either Text ByteString
forall a b. b -> Either a b
Right
defaultSDKAesonOptions :: String -> Options
defaultSDKAesonOptions :: String -> Options
defaultSDKAesonOptions prefix :: String
prefix = Int -> (String -> String) -> Options
aesonDrop (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
prefix) String -> String
snakeCase