{- |
Module      : Conformance.Evidence.Asset
Description : One asset movement in edge evidence
License     : Apache-2.0

Edge evidence reports what a keyed mint moved, and a movement is
identified by its policy and asset name — a quantity alone cannot say
which key a token belongs to. This module is the single owner of that
shape and its JSON encoding; @Conformance.Receipt@ re-exports it, so the
public import path a caller already uses is unchanged.
-}
module Conformance.Evidence.Asset
    ( AssetEntry (..)
    ) where

import Data.Aeson
    ( FromJSON (..)
    , ToJSON (..)
    , object
    , withObject
    , (.:)
    , (.=)
    )
import Data.Text (Text)

{- | One asset movement, named by its policy and asset name.

The registry's token identity is @(policy, key)@ and nothing else, so a
row about a keyed mint has to report both. A quantity alone cannot
distinguish "one token at this key" from "one token at some other key".
-}
data AssetEntry = AssetEntry
    { AssetEntry -> Text
aePolicy :: !Text
    , AssetEntry -> Text
aeName :: !Text
    , AssetEntry -> Integer
aeQuantity :: !Integer
    }
    deriving stock (Int -> AssetEntry -> ShowS
[AssetEntry] -> ShowS
AssetEntry -> String
(Int -> AssetEntry -> ShowS)
-> (AssetEntry -> String)
-> ([AssetEntry] -> ShowS)
-> Show AssetEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AssetEntry -> ShowS
showsPrec :: Int -> AssetEntry -> ShowS
$cshow :: AssetEntry -> String
show :: AssetEntry -> String
$cshowList :: [AssetEntry] -> ShowS
showList :: [AssetEntry] -> ShowS
Show, AssetEntry -> AssetEntry -> Bool
(AssetEntry -> AssetEntry -> Bool)
-> (AssetEntry -> AssetEntry -> Bool) -> Eq AssetEntry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AssetEntry -> AssetEntry -> Bool
== :: AssetEntry -> AssetEntry -> Bool
$c/= :: AssetEntry -> AssetEntry -> Bool
/= :: AssetEntry -> AssetEntry -> Bool
Eq)

instance FromJSON AssetEntry where
    parseJSON :: Value -> Parser AssetEntry
parseJSON = String
-> (Object -> Parser AssetEntry) -> Value -> Parser AssetEntry
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"AssetEntry" ((Object -> Parser AssetEntry) -> Value -> Parser AssetEntry)
-> (Object -> Parser AssetEntry) -> Value -> Parser AssetEntry
forall a b. (a -> b) -> a -> b
$ \Object
o ->
        Text -> Text -> Integer -> AssetEntry
AssetEntry (Text -> Text -> Integer -> AssetEntry)
-> Parser Text -> Parser (Text -> Integer -> AssetEntry)
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
"policy" Parser (Text -> Integer -> AssetEntry)
-> Parser Text -> Parser (Integer -> AssetEntry)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"name" Parser (Integer -> AssetEntry)
-> Parser Integer -> Parser AssetEntry
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Key -> Parser Integer
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"quantity"

instance ToJSON AssetEntry where
    toJSON :: AssetEntry -> Value
toJSON AssetEntry
a =
        [Pair] -> Value
object
            [ Key
"policy" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= AssetEntry -> Text
aePolicy AssetEntry
a
            , Key
"name" Key -> Text -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= AssetEntry -> Text
aeName AssetEntry
a
            , Key
"quantity" Key -> Integer -> Pair
forall v. ToJSON v => Key -> v -> Pair
forall e kv v. (KeyValue e kv, ToJSON v) => Key -> v -> kv
.= AssetEntry -> Integer
aeQuantity AssetEntry
a
            ]