{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Cardano.Ledger.Metadata (
Metadatum (..),
) where
import Cardano.Ledger.Binary (
DecCBOR (decCBOR),
Decoder,
DecoderError (..),
EncCBOR (encCBOR),
Encoding,
TokenType (..),
cborError,
decodeBreakOr,
decodeBytesIndef,
decodeInteger,
decodeListLen,
decodeListLenIndef,
decodeMapLen,
decodeMapLenIndef,
decodeString,
decodeStringIndef,
encodeInteger,
encodeListLen,
encodeMapLen,
encodeString,
getDecoderVersion,
natVersion,
peekTokenType,
)
import Cardano.Ledger.Orphans ()
import Control.Applicative ((<|>))
import Control.DeepSeq (NFData (rnf))
import Control.Monad (when)
import Data.Aeson (FromJSON (..), ToJSON (..), (.:), (.=))
import qualified Data.Aeson as Aeson
import Data.Array.Byte (ByteArray (..))
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base16 as B16
import qualified Data.ByteString.Short as SBS
import Data.MemPack.Buffer (byteArrayToShortByteString)
import qualified Data.Primitive.ByteArray as Prim
import qualified Data.Text as T
import qualified Data.Text.Encoding as TE
import qualified Data.Text.Foreign as TF
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks (..))
data Metadatum
= Map ![(Metadatum, Metadatum)]
| List ![Metadatum]
| I !Integer
| B !ByteArray
| S !T.Text
deriving stock (Int -> Metadatum -> ShowS
[Metadatum] -> ShowS
Metadatum -> String
(Int -> Metadatum -> ShowS)
-> (Metadatum -> String)
-> ([Metadatum] -> ShowS)
-> Show Metadatum
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Metadatum -> ShowS
showsPrec :: Int -> Metadatum -> ShowS
$cshow :: Metadatum -> String
show :: Metadatum -> String
$cshowList :: [Metadatum] -> ShowS
showList :: [Metadatum] -> ShowS
Show, Metadatum -> Metadatum -> Bool
(Metadatum -> Metadatum -> Bool)
-> (Metadatum -> Metadatum -> Bool) -> Eq Metadatum
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Metadatum -> Metadatum -> Bool
== :: Metadatum -> Metadatum -> Bool
$c/= :: Metadatum -> Metadatum -> Bool
/= :: Metadatum -> Metadatum -> Bool
Eq, Eq Metadatum
Eq Metadatum =>
(Metadatum -> Metadatum -> Ordering)
-> (Metadatum -> Metadatum -> Bool)
-> (Metadatum -> Metadatum -> Bool)
-> (Metadatum -> Metadatum -> Bool)
-> (Metadatum -> Metadatum -> Bool)
-> (Metadatum -> Metadatum -> Metadatum)
-> (Metadatum -> Metadatum -> Metadatum)
-> Ord Metadatum
Metadatum -> Metadatum -> Bool
Metadatum -> Metadatum -> Ordering
Metadatum -> Metadatum -> Metadatum
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Metadatum -> Metadatum -> Ordering
compare :: Metadatum -> Metadatum -> Ordering
$c< :: Metadatum -> Metadatum -> Bool
< :: Metadatum -> Metadatum -> Bool
$c<= :: Metadatum -> Metadatum -> Bool
<= :: Metadatum -> Metadatum -> Bool
$c> :: Metadatum -> Metadatum -> Bool
> :: Metadatum -> Metadatum -> Bool
$c>= :: Metadatum -> Metadatum -> Bool
>= :: Metadatum -> Metadatum -> Bool
$cmax :: Metadatum -> Metadatum -> Metadatum
max :: Metadatum -> Metadatum -> Metadatum
$cmin :: Metadatum -> Metadatum -> Metadatum
min :: Metadatum -> Metadatum -> Metadatum
Ord, (forall x. Metadatum -> Rep Metadatum x)
-> (forall x. Rep Metadatum x -> Metadatum) -> Generic Metadatum
forall x. Rep Metadatum x -> Metadatum
forall x. Metadatum -> Rep Metadatum x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Metadatum -> Rep Metadatum x
from :: forall x. Metadatum -> Rep Metadatum x
$cto :: forall x. Rep Metadatum x -> Metadatum
to :: forall x. Rep Metadatum x -> Metadatum
Generic)
instance NoThunks Metadatum
instance NFData Metadatum where
rnf :: Metadatum -> ()
rnf = \case
Map [(Metadatum, Metadatum)]
m -> [(Metadatum, Metadatum)] -> ()
forall a. NFData a => a -> ()
rnf [(Metadatum, Metadatum)]
m
List [Metadatum]
l -> [Metadatum] -> ()
forall a. NFData a => a -> ()
rnf [Metadatum]
l
I Integer
_ -> ()
B ByteArray
_ -> ()
S Text
_ -> ()
instance EncCBOR Metadatum where
encCBOR :: Metadatum -> Encoding
encCBOR = Metadatum -> Encoding
encodeMetadatum
instance DecCBOR Metadatum where
decCBOR :: forall s. Decoder s Metadatum
decCBOR = Decoder s Metadatum
forall s. Decoder s Metadatum
decodeMetadatum
instance ToJSON Metadatum where
toJSON :: Metadatum -> Value
toJSON = \case
Map [(Metadatum, Metadatum)]
kvs ->
[Pair] -> Value
Aeson.object
[ Key
"map"
Key -> [Value] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [ [Pair] -> Value
Aeson.object
[ Key
"k" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Metadatum -> Value
forall a. ToJSON a => a -> Value
toJSON Metadatum
k
, Key
"v" Key -> Value -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Metadatum -> Value
forall a. ToJSON a => a -> Value
toJSON Metadatum
v
]
| (Metadatum
k, Metadatum
v) <- [(Metadatum, Metadatum)]
kvs
]
]
List [Metadatum]
xs -> [Pair] -> Value
Aeson.object [Key
"list" Key -> [Metadatum] -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= [Metadatum]
xs]
I Integer
n -> [Pair] -> Value
Aeson.object [Key
"int" Key -> Integer -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Integer
n]
B ByteArray
ba ->
[Pair] -> Value
Aeson.object
[ Key
"bytes" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= ByteString -> Text
TE.decodeLatin1 (ByteString -> ByteString
B16.encode (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ShortByteString -> ByteString
SBS.fromShort (ShortByteString -> ByteString) -> ShortByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteArray -> ShortByteString
byteArrayToShortByteString ByteArray
ba)
]
S Text
t -> [Pair] -> Value
Aeson.object [Key
"string" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= Text
t]
instance FromJSON Metadatum where
parseJSON :: Value -> Parser Metadatum
parseJSON =
String -> (Object -> Parser Metadatum) -> Value -> Parser Metadatum
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Metadatum" ((Object -> Parser Metadatum) -> Value -> Parser Metadatum)
-> (Object -> Parser Metadatum) -> Value -> Parser Metadatum
forall a b. (a -> b) -> a -> b
$ \Object
o ->
([(Metadatum, Metadatum)] -> Metadatum
Map ([(Metadatum, Metadatum)] -> Metadatum)
-> Parser [(Metadatum, Metadatum)] -> Parser Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Object
o Object -> Key -> Parser [Value]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"map" Parser [Value]
-> ([Value] -> Parser [(Metadatum, Metadatum)])
-> Parser [(Metadatum, Metadatum)]
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Value -> Parser (Metadatum, Metadatum))
-> [Value] -> Parser [(Metadatum, Metadatum)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Value -> Parser (Metadatum, Metadatum)
parseMetadatumKeyValue))
Parser Metadatum -> Parser Metadatum -> Parser Metadatum
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Metadatum] -> Metadatum
List ([Metadatum] -> Metadatum)
-> Parser [Metadatum] -> Parser Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser [Metadatum]
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"list")
Parser Metadatum -> Parser Metadatum -> Parser Metadatum
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Integer -> Metadatum
I (Integer -> Metadatum) -> Parser Integer -> Parser Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Integer
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"int")
Parser Metadatum -> Parser Metadatum -> Parser Metadatum
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ( Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"bytes" Parser Text -> (Text -> Parser Metadatum) -> Parser Metadatum
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Text
s ->
case ByteString -> Either String ByteString
B16.decode (Text -> ByteString
TE.encodeUtf8 Text
s) of
Left String
e -> String -> Parser Metadatum
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Metadatum) -> String -> Parser Metadatum
forall a b. (a -> b) -> a -> b
$ String
"Metadatum bytes: invalid hex: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
e
Right ByteString
bs -> Metadatum -> Parser Metadatum
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Metadatum -> Parser Metadatum) -> Metadatum -> Parser Metadatum
forall a b. (a -> b) -> a -> b
$ ByteArray -> Metadatum
B ([Word8] -> ByteArray
forall a. Prim a => [a] -> ByteArray
Prim.byteArrayFromList (ByteString -> [Word8]
BS.unpack ByteString
bs))
)
Parser Metadatum -> Parser Metadatum -> Parser Metadatum
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Text -> Metadatum
S (Text -> Metadatum) -> Parser Text -> Parser Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"string")
where
parseMetadatumKeyValue :: Value -> Parser (Metadatum, Metadatum)
parseMetadatumKeyValue =
String
-> (Object -> Parser (Metadatum, Metadatum))
-> Value
-> Parser (Metadatum, Metadatum)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Metadatum Inner Map" ((Object -> Parser (Metadatum, Metadatum))
-> Value -> Parser (Metadatum, Metadatum))
-> (Object -> Parser (Metadatum, Metadatum))
-> Value
-> Parser (Metadatum, Metadatum)
forall a b. (a -> b) -> a -> b
$ \Object
kvo -> do
!k <- Object
kvo Object -> Key -> Parser Value
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"k" Parser Value -> (Value -> Parser Metadatum) -> Parser Metadatum
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> Parser Metadatum
forall a. FromJSON a => Value -> Parser a
parseJSON
!v <- kvo .: "v" >>= parseJSON
pure (k, v)
encodeMetadatum :: Metadatum -> Encoding
encodeMetadatum :: Metadatum -> Encoding
encodeMetadatum (I Integer
n) = Integer -> Encoding
encodeInteger Integer
n
encodeMetadatum (B ByteArray
ba) = ByteArray -> Encoding
forall a. EncCBOR a => a -> Encoding
encCBOR ByteArray
ba
encodeMetadatum (S Text
s) = Text -> Encoding
encodeString Text
s
encodeMetadatum (List [Metadatum]
xs) =
Word -> Encoding
encodeListLen (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Metadatum] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Metadatum]
xs))
Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> [Encoding] -> Encoding
forall a. Monoid a => [a] -> a
mconcat
[ Metadatum -> Encoding
encodeMetadatum Metadatum
x
| Metadatum
x <- [Metadatum]
xs
]
encodeMetadatum (Map [(Metadatum, Metadatum)]
kvs) =
Word -> Encoding
encodeMapLen (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([(Metadatum, Metadatum)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Metadatum, Metadatum)]
kvs))
Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> [Encoding] -> Encoding
forall a. Monoid a => [a] -> a
mconcat
[ Metadatum -> Encoding
encodeMetadatum Metadatum
k Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> Metadatum -> Encoding
encodeMetadatum Metadatum
v
| (Metadatum
k, Metadatum
v) <- [(Metadatum, Metadatum)]
kvs
]
decodeMetadatum :: Decoder s Metadatum
decodeMetadatum :: forall s. Decoder s Metadatum
decodeMetadatum = do
dv <- Decoder s Version
forall s. Decoder s Version
getDecoderVersion
let checkSizes = Version
dv Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
> forall (v :: Natural).
(KnownNat v, MinVersion <= v, v <= MaxVersion) =>
Version
natVersion @2
tkty <- peekTokenType
case tkty of
TokenType
TypeUInt -> Integer -> Metadatum
I (Integer -> Metadatum) -> Decoder s Integer -> Decoder s Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s Integer
forall s. Decoder s Integer
decodeInteger
TokenType
TypeUInt64 -> Integer -> Metadatum
I (Integer -> Metadatum) -> Decoder s Integer -> Decoder s Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s Integer
forall s. Decoder s Integer
decodeInteger
TokenType
TypeNInt -> Integer -> Metadatum
I (Integer -> Metadatum) -> Decoder s Integer -> Decoder s Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s Integer
forall s. Decoder s Integer
decodeInteger
TokenType
TypeNInt64 -> Integer -> Metadatum
I (Integer -> Metadatum) -> Decoder s Integer -> Decoder s Metadatum
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s Integer
forall s. Decoder s Integer
decodeInteger
TokenType
TypeBytes -> do
!ba <- Decoder s ByteArray
forall s. Decoder s ByteArray
forall a s. DecCBOR a => Decoder s a
decCBOR
when (checkSizes && Prim.sizeofByteArray ba > 64) $
decodeError "bytes .size (0..64): bytestring exceeds 64 bytes"
return (B ba)
TokenType
TypeBytesIndef -> do
Decoder s ()
forall s. Decoder s ()
decodeBytesIndef
!ba <- [ByteArray] -> Decoder s ByteArray
forall s. [ByteArray] -> Decoder s ByteArray
decodeBytesIndefLen []
when (checkSizes && Prim.sizeofByteArray ba > 64) $
decodeError "bytes .size (0..64): bytestring exceeds 64 bytes"
return (B ba)
TokenType
TypeString -> do
!x <- Decoder s Text
forall s. Decoder s Text
decodeString
when (checkSizes && TF.lengthWord8 x > 64) $
decodeError "text .size (0..64): text exceeds 64 bytes"
return (S x)
TokenType
TypeStringIndef -> do
Decoder s ()
forall s. Decoder s ()
decodeStringIndef
!x <- [Text] -> Decoder s Text
forall s. [Text] -> Decoder s Text
decodeStringIndefLen []
when (checkSizes && TF.lengthWord8 x > 64) $
decodeError "text .size (0..64): text exceeds 64 bytes"
return (S x)
TokenType
TypeListLen -> do
n <- Decoder s Int
forall s. Decoder s Int
decodeListLen
xs <- decodeListN n []
return (List xs)
TokenType
TypeListLen64 -> do
n <- Decoder s Int
forall s. Decoder s Int
decodeListLen
xs <- decodeListN n []
return (List xs)
TokenType
TypeListLenIndef -> do
Decoder s ()
forall s. Decoder s ()
decodeListLenIndef
xs <- [Metadatum] -> Decoder s [Metadatum]
forall s. [Metadatum] -> Decoder s [Metadatum]
decodeListIndefLen []
return (List xs)
TokenType
TypeMapLen -> do
n <- Decoder s Int
forall s. Decoder s Int
decodeMapLen
xs <- decodeMapN n []
return (Map xs)
TokenType
TypeMapLen64 -> do
n <- Decoder s Int
forall s. Decoder s Int
decodeMapLen
xs <- decodeMapN n []
return (Map xs)
TokenType
TypeMapLenIndef -> do
Decoder s ()
forall s. Decoder s ()
decodeMapLenIndef
xs <- [(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
forall s.
[(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
decodeMapIndefLen []
return (Map xs)
TokenType
_ -> Text -> Decoder s Metadatum
forall {m :: * -> *} {a}. MonadFail m => Text -> m a
decodeError (Text
"Unsupported token type " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (TokenType -> String
forall a. Show a => a -> String
show TokenType
tkty))
where
decodeError :: Text -> m a
decodeError Text
msg = DecoderError -> m a
forall (m :: * -> *) e a. (MonadFail m, Buildable e) => e -> m a
cborError (Text -> Text -> DecoderError
DecoderErrorCustom Text
"metadata" Text
msg)
decodeBytesIndefLen :: [ByteArray] -> Decoder s ByteArray
decodeBytesIndefLen :: forall s. [ByteArray] -> Decoder s ByteArray
decodeBytesIndefLen [ByteArray]
acc = do
stop <- Decoder s Bool
forall s. Decoder s Bool
decodeBreakOr
if stop
then return $! mconcat $ reverse acc
else do
!ba <- decCBOR
decodeBytesIndefLen (ba : acc)
decodeStringIndefLen :: [T.Text] -> Decoder s T.Text
decodeStringIndefLen :: forall s. [Text] -> Decoder s Text
decodeStringIndefLen [Text]
acc = do
stop <- Decoder s Bool
forall s. Decoder s Bool
decodeBreakOr
if stop
then return $! T.concat (reverse acc)
else do
!str <- decodeString
decodeStringIndefLen (str : acc)
decodeListN :: Int -> [Metadatum] -> Decoder s [Metadatum]
decodeListN :: forall s. Int -> [Metadatum] -> Decoder s [Metadatum]
decodeListN !Int
n [Metadatum]
acc =
case Int
n of
Int
0 -> [Metadatum] -> Decoder s [Metadatum]
forall a. a -> Decoder s a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Metadatum] -> Decoder s [Metadatum])
-> [Metadatum] -> Decoder s [Metadatum]
forall a b. (a -> b) -> a -> b
$! [Metadatum] -> [Metadatum]
forall a. [a] -> [a]
reverse [Metadatum]
acc
Int
_ -> do
!t <- Decoder s Metadatum
forall s. Decoder s Metadatum
decodeMetadatum
decodeListN (n - 1) (t : acc)
decodeListIndefLen :: [Metadatum] -> Decoder s [Metadatum]
decodeListIndefLen :: forall s. [Metadatum] -> Decoder s [Metadatum]
decodeListIndefLen [Metadatum]
acc = do
stop <- Decoder s Bool
forall s. Decoder s Bool
decodeBreakOr
if stop
then return $! reverse acc
else do
!tm <- decodeMetadatum
decodeListIndefLen (tm : acc)
decodeMapN :: Int -> [(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
decodeMapN :: forall s.
Int
-> [(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
decodeMapN !Int
n [(Metadatum, Metadatum)]
acc =
case Int
n of
Int
0 -> [(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
forall a. a -> Decoder s a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)])
-> [(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
forall a b. (a -> b) -> a -> b
$! [(Metadatum, Metadatum)] -> [(Metadatum, Metadatum)]
forall a. [a] -> [a]
reverse [(Metadatum, Metadatum)]
acc
Int
_ -> do
!tm <- Decoder s Metadatum
forall s. Decoder s Metadatum
decodeMetadatum
!tm' <- decodeMetadatum
decodeMapN (n - 1) ((tm, tm') : acc)
decodeMapIndefLen :: [(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
decodeMapIndefLen :: forall s.
[(Metadatum, Metadatum)] -> Decoder s [(Metadatum, Metadatum)]
decodeMapIndefLen [(Metadatum, Metadatum)]
acc = do
stop <- Decoder s Bool
forall s. Decoder s Bool
decodeBreakOr
if stop
then return $! reverse acc
else do
!tm <- decodeMetadatum
!tm' <- decodeMetadatum
decodeMapIndefLen ((tm, tm') : acc)