{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}

{- | Provides Data and Scott encoded  asset class types and utility
  functions.
-}
module Plutarch.Extra.AssetClass (
  -- * AssetClass - Hask
  AssetClass (AssetClass, symbol, name),
  assetClassValue,

  -- * AssetClass - Plutarch
  PAssetClass (PAssetClass, psymbol, pname),
  passetClass,
  passetClassT,
  adaSymbolData,
  isAdaClass,
  adaClass,
  padaClass,
  emptyTokenNameData,
  psymbolAssetClass,
  psymbolAssetClassT,
  pconstantClass,
  pconstantClassT,

  -- * AssetClassData - Plutarch
  PAssetClassData (PAssetClassData),
  passetClassData,
  passetClassDataT,

  -- * Scott <-> Data conversions
  ptoScottEncoding,
  pfromScottEncoding,
  pviaScottEncoding,

  -- * Modifiers for QuickCheck
  AdaClassPresence (..),
  GenAssetClass (..),
) where

import Data.Aeson (
  FromJSON,
  FromJSONKey,
  ToJSON,
  ToJSONKey,
 )
import Data.Tagged (Tagged (Tagged, unTagged), untag)
import Generics.SOP qualified as SOP
import Optics.Getter (A_Getter, view)
import Optics.Label (LabelOptic, LabelOptic', labelOptic)
import Optics.Lens (A_Lens)
import Optics.Optic (Is, (%%))
import Optics.Setter (set)
import Optics.TH (makeFieldLabelsNoPrefix)
import Plutarch.Api.V1 (PCurrencySymbol, PTokenName)
import Plutarch.DataRepr (PDataFields)
import Plutarch.Extra.Applicative (ppure)
import Plutarch.Extra.IsData (
  DerivePConstantViaDataList (DerivePConstantViaDataList),
  ProductIsData (ProductIsData),
 )
import Plutarch.Extra.Record (mkRecordConstr, (.&), (.=))
import Plutarch.Extra.Tagged (PTagged)
import Plutarch.Lift (
  PConstantDecl,
  PUnsafeLiftDecl (PLifted),
 )
import Plutarch.Orphans ()
import Plutarch.Test.QuickCheck.Instances ()
import Plutarch.Test.QuickCheck.Modifiers (
  AdaSymbolPresence (WithAdaSymbol, WithoutAdaSymbol),
  GenCurrencySymbol (GenCurrencySymbol),
 )
import PlutusLedgerApi.V1.Value (CurrencySymbol, TokenName)
import PlutusLedgerApi.V1.Value qualified as Value
import PlutusTx qualified
import Ply.Core.Class (
  PlyArg (
    UPLCRep,
    toBuiltinArg,
    toBuiltinArgData
  ),
 )
import Ply.Plutarch (PlyArgOf)
import Test.QuickCheck (
  Arbitrary (arbitrary, shrink),
  CoArbitrary (coarbitrary),
  Function (function),
  functionMap,
 )

--------------------------------------------------------------------------------
-- AssetClass & Variants

{- | A version of 'PlutusTx.AssetClass', with a tag for currency.

 @since 3.10.0
-}
data AssetClass = AssetClass
  { AssetClass -> CurrencySymbol
symbol :: CurrencySymbol
  -- ^ @since 3.9.0
  , AssetClass -> TokenName
name :: TokenName
  -- ^ @since 3.9.0
  }
  deriving stock
    ( -- | @since 3.9.0
      AssetClass -> AssetClass -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AssetClass -> AssetClass -> Bool
$c/= :: AssetClass -> AssetClass -> Bool
== :: AssetClass -> AssetClass -> Bool
$c== :: AssetClass -> AssetClass -> Bool
Eq
    , -- | @since 3.9.0
      Eq AssetClass
AssetClass -> AssetClass -> Bool
AssetClass -> AssetClass -> Ordering
AssetClass -> AssetClass -> AssetClass
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
min :: AssetClass -> AssetClass -> AssetClass
$cmin :: AssetClass -> AssetClass -> AssetClass
max :: AssetClass -> AssetClass -> AssetClass
$cmax :: AssetClass -> AssetClass -> AssetClass
>= :: AssetClass -> AssetClass -> Bool
$c>= :: AssetClass -> AssetClass -> Bool
> :: AssetClass -> AssetClass -> Bool
$c> :: AssetClass -> AssetClass -> Bool
<= :: AssetClass -> AssetClass -> Bool
$c<= :: AssetClass -> AssetClass -> Bool
< :: AssetClass -> AssetClass -> Bool
$c< :: AssetClass -> AssetClass -> Bool
compare :: AssetClass -> AssetClass -> Ordering
$ccompare :: AssetClass -> AssetClass -> Ordering
Ord
    , -- | @since 3.9.0
      Int -> AssetClass -> ShowS
[AssetClass] -> ShowS
AssetClass -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AssetClass] -> ShowS
$cshowList :: [AssetClass] -> ShowS
show :: AssetClass -> String
$cshow :: AssetClass -> String
showsPrec :: Int -> AssetClass -> ShowS
$cshowsPrec :: Int -> AssetClass -> ShowS
Show
    , -- | @since 3.9.0
      forall x. Rep AssetClass x -> AssetClass
forall x. AssetClass -> Rep AssetClass x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep AssetClass x -> AssetClass
$cfrom :: forall x. AssetClass -> Rep AssetClass x
Generic
    )
  deriving anyclass
    ( -- | @since 3.9.0
      [AssetClass] -> Encoding
[AssetClass] -> Value
AssetClass -> Encoding
AssetClass -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [AssetClass] -> Encoding
$ctoEncodingList :: [AssetClass] -> Encoding
toJSONList :: [AssetClass] -> Value
$ctoJSONList :: [AssetClass] -> Value
toEncoding :: AssetClass -> Encoding
$ctoEncoding :: AssetClass -> Encoding
toJSON :: AssetClass -> Value
$ctoJSON :: AssetClass -> Value
ToJSON
    , -- | @since 3.9.0
      Value -> Parser [AssetClass]
Value -> Parser AssetClass
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [AssetClass]
$cparseJSONList :: Value -> Parser [AssetClass]
parseJSON :: Value -> Parser AssetClass
$cparseJSON :: Value -> Parser AssetClass
FromJSON
    , -- | @since 3.9.0
      FromJSONKeyFunction [AssetClass]
FromJSONKeyFunction AssetClass
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
fromJSONKeyList :: FromJSONKeyFunction [AssetClass]
$cfromJSONKeyList :: FromJSONKeyFunction [AssetClass]
fromJSONKey :: FromJSONKeyFunction AssetClass
$cfromJSONKey :: FromJSONKeyFunction AssetClass
FromJSONKey
    , -- | @since 3.9.0
      ToJSONKeyFunction [AssetClass]
ToJSONKeyFunction AssetClass
forall a.
ToJSONKeyFunction a -> ToJSONKeyFunction [a] -> ToJSONKey a
toJSONKeyList :: ToJSONKeyFunction [AssetClass]
$ctoJSONKeyList :: ToJSONKeyFunction [AssetClass]
toJSONKey :: ToJSONKeyFunction AssetClass
$ctoJSONKey :: ToJSONKeyFunction AssetClass
ToJSONKey
    , -- | @since 3.10.0
      All SListI (Code AssetClass)
Rep AssetClass -> AssetClass
AssetClass -> Rep AssetClass
forall a.
All SListI (Code a) -> (a -> Rep a) -> (Rep a -> a) -> Generic a
to :: Rep AssetClass -> AssetClass
$cto :: Rep AssetClass -> AssetClass
from :: AssetClass -> Rep AssetClass
$cfrom :: AssetClass -> Rep AssetClass
SOP.Generic
    )
  deriving
    ( -- | @since 3.10.0
      AssetClass -> BuiltinData
forall a. (a -> BuiltinData) -> ToData a
toBuiltinData :: AssetClass -> BuiltinData
$ctoBuiltinData :: AssetClass -> BuiltinData
PlutusTx.ToData
    , -- | @since 3.10.0
      BuiltinData -> Maybe AssetClass
forall a. (BuiltinData -> Maybe a) -> FromData a
fromBuiltinData :: BuiltinData -> Maybe AssetClass
$cfromBuiltinData :: BuiltinData -> Maybe AssetClass
PlutusTx.FromData
    , -- | @since 3.14.2
      BuiltinData -> AssetClass
forall a. (BuiltinData -> a) -> UnsafeFromData a
unsafeFromBuiltinData :: BuiltinData -> AssetClass
$cunsafeFromBuiltinData :: BuiltinData -> AssetClass
PlutusTx.UnsafeFromData
    )
    via Plutarch.Extra.IsData.ProductIsData AssetClass
  deriving
    ( -- | @since 3.10.0
      PUnsafeLiftDecl (PConstanted AssetClass)
Includes DefaultUni (PConstantRepr AssetClass)
PConstantRepr AssetClass -> Maybe AssetClass
AssetClass -> PConstantRepr AssetClass
forall h.
PUnsafeLiftDecl (PConstanted h)
-> Includes DefaultUni (PConstantRepr h)
-> (h -> PConstantRepr h)
-> (PConstantRepr h -> Maybe h)
-> PConstantDecl h
pconstantFromRepr :: PConstantRepr AssetClass -> Maybe AssetClass
$cpconstantFromRepr :: PConstantRepr AssetClass -> Maybe AssetClass
pconstantToRepr :: AssetClass -> PConstantRepr AssetClass
$cpconstantToRepr :: AssetClass -> PConstantRepr AssetClass
Plutarch.Lift.PConstantDecl
    )
    via ( Plutarch.Extra.IsData.DerivePConstantViaDataList
            AssetClass
            PAssetClassData
        )

{- | A Scott-encoded Plutarch equivalent to 'AssetClass'.

 @since 3.10.0
-}
data PAssetClass (s :: S) = PAssetClass
  { forall (s :: S). PAssetClass s -> Term s (PAsData PCurrencySymbol)
psymbol :: Term s (PAsData PCurrencySymbol)
  -- ^ @since 3.9.0
  , forall (s :: S). PAssetClass s -> Term s (PAsData PTokenName)
pname :: Term s (PAsData PTokenName)
  -- ^ @since 3.9.0
  }
  deriving stock
    ( -- | @since 3.9.0
      forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x. Rep (PAssetClass s) x -> PAssetClass s
forall (s :: S) x. PAssetClass s -> Rep (PAssetClass s) x
$cto :: forall (s :: S) x. Rep (PAssetClass s) x -> PAssetClass s
$cfrom :: forall (s :: S) x. PAssetClass s -> Rep (PAssetClass s) x
Generic
    )
  deriving anyclass
    ( -- | @since 3.9.0
      forall (s :: S).
Term s PAssetClass -> Term s PAssetClass -> Term s PBool
forall (t :: PType).
(forall (s :: S). Term s t -> Term s t -> Term s PBool) -> PEq t
#== :: forall (s :: S).
Term s PAssetClass -> Term s PAssetClass -> Term s PBool
$c#== :: forall (s :: S).
Term s PAssetClass -> Term s PAssetClass -> Term s PBool
PEq
    , -- | @since 3.9.0
      forall (s :: S). PAssetClass s -> Term s (PInner PAssetClass)
forall (s :: S) (b :: PType).
Term s (PInner PAssetClass)
-> (PAssetClass s -> Term s b) -> Term s b
forall (a :: PType).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: PType).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
pmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PAssetClass)
-> (PAssetClass s -> Term s b) -> Term s b
$cpmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PAssetClass)
-> (PAssetClass s -> Term s b) -> Term s b
pcon' :: forall (s :: S). PAssetClass s -> Term s (PInner PAssetClass)
$cpcon' :: forall (s :: S). PAssetClass s -> Term s (PInner PAssetClass)
PlutusType
    )

-- | @since 3.10.0
instance DerivePlutusType PAssetClass where
  type DPTStrat _ = PlutusTypeScott

-- | @since 3.10.0
passetClass ::
  forall (s :: S).
  Term s (PCurrencySymbol :--> PTokenName :--> PAssetClass)
passetClass :: forall (s :: S).
Term s (PCurrencySymbol :--> (PTokenName :--> PAssetClass))
passetClass = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PCurrencySymbol
sym Term s PTokenName
tk ->
    forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PAsData PCurrencySymbol)
-> Term s (PAsData PTokenName) -> PAssetClass s
PAssetClass (forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s PCurrencySymbol
sym) (forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s PTokenName
tk)

-- | @since 3.10.4
passetClassT ::
  forall {k :: Type} (unit :: k) (s :: S).
  Term s (PCurrencySymbol :--> PTokenName :--> PTagged unit PAssetClass)
passetClassT :: forall {k} (unit :: k) (s :: S).
Term
  s (PCurrencySymbol :--> (PTokenName :--> PTagged unit PAssetClass))
passetClassT = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PCurrencySymbol
sym Term s PTokenName
tk ->
    forall (f :: PType -> PType) (a :: PType) (s :: S).
(PApplicative f, PSubcategory f a) =>
Term s (a :--> f a)
ppure forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (s :: S).
Term s (PCurrencySymbol :--> (PTokenName :--> PAssetClass))
passetClass forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s PCurrencySymbol
sym forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s PTokenName
tk

-- | @since 3.10.0
pconstantClass ::
  forall (a :: Type) (k :: Type) (s :: S).
  ( Is k A_Getter
  , LabelOptic' "symbol" k a CurrencySymbol
  , LabelOptic' "name" k a TokenName
  ) =>
  a ->
  Term s PAssetClass
pconstantClass :: forall a k (s :: S).
(Is k A_Getter, LabelOptic' "symbol" k a CurrencySymbol,
 LabelOptic' "name" k a TokenName) =>
a -> Term s PAssetClass
pconstantClass a
ac =
  forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$
    forall (s :: S).
Term s (PAsData PCurrencySymbol)
-> Term s (PAsData PTokenName) -> PAssetClass s
PAssetClass
      (forall (p :: PType) h (s :: S).
(ToData h, PLifted p ~ h, PConstanted h ~ p) =>
h -> Term s (PAsData p)
pconstantData forall a b. (a -> b) -> a -> b
$ forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "symbol" a => a
#symbol a
ac)
      (forall (p :: PType) h (s :: S).
(ToData h, PLifted p ~ h, PConstanted h ~ p) =>
h -> Term s (PAsData p)
pconstantData forall a b. (a -> b) -> a -> b
$ forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name a
ac)

-- | @since 3.10.4
pconstantClassT ::
  forall {k :: Type} (unit :: k) (s :: S).
  Tagged unit AssetClass ->
  Term s (PTagged unit PAssetClass)
pconstantClassT :: forall {k} (unit :: k) (s :: S).
Tagged unit AssetClass -> Term s (PTagged unit PAssetClass)
pconstantClassT (Tagged (AssetClass CurrencySymbol
sym TokenName
tk)) =
  forall (f :: PType -> PType) (a :: PType) (s :: S).
(PApplicative f, PSubcategory f a) =>
Term s (a :--> f a)
ppure forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PAsData PCurrencySymbol)
-> Term s (PAsData PTokenName) -> PAssetClass s
PAssetClass (forall (p :: PType) h (s :: S).
(ToData h, PLifted p ~ h, PConstanted h ~ p) =>
h -> Term s (PAsData p)
pconstantData CurrencySymbol
sym) (forall (p :: PType) h (s :: S).
(ToData h, PLifted p ~ h, PConstanted h ~ p) =>
h -> Term s (PAsData p)
pconstantData TokenName
tk)

{- | Construct a 'PAssetClass' with empty 'pname'.
 @since 3.9.0
-}
psymbolAssetClass ::
  forall (s :: S).
  Term s (PCurrencySymbol :--> PAssetClass)
psymbolAssetClass :: forall (s :: S). Term s (PCurrencySymbol :--> PAssetClass)
psymbolAssetClass = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PCurrencySymbol
sym ->
    forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PAsData PCurrencySymbol)
-> Term s (PAsData PTokenName) -> PAssetClass s
PAssetClass (forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s PCurrencySymbol
sym) forall (s :: S). Term s (PAsData PTokenName)
emptyTokenNameData

{- | Tagged version of `psymbolAssetClass`
 @since 3.10.4
-}
psymbolAssetClassT ::
  forall {k :: Type} (unit :: k) (s :: S).
  Term s (PCurrencySymbol :--> PTagged unit PAssetClass)
psymbolAssetClassT :: forall {k} (unit :: k) (s :: S).
Term s (PCurrencySymbol :--> PTagged unit PAssetClass)
psymbolAssetClassT = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PCurrencySymbol
sym ->
    forall (f :: PType -> PType) (a :: PType) (s :: S).
(PApplicative f, PSubcategory f a) =>
Term s (a :--> f a)
ppure forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$ forall (s :: S).
Term s (PAsData PCurrencySymbol)
-> Term s (PAsData PTokenName) -> PAssetClass s
PAssetClass (forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s PCurrencySymbol
sym) forall (s :: S). Term s (PAsData PTokenName)
emptyTokenNameData

--------------------------------------------------------------------------------
-- Simple Helpers

{- | Check whether an 'AssetClass' corresponds to Ada.

 @since 3.9.0
-}
isAdaClass ::
  forall (a :: Type) (k :: Type).
  ( Is k A_Getter
  , LabelOptic' "symbol" k a CurrencySymbol
  , LabelOptic' "name" k a TokenName
  ) =>
  a ->
  Bool
isAdaClass :: forall a k.
(Is k A_Getter, LabelOptic' "symbol" k a CurrencySymbol,
 LabelOptic' "name" k a TokenName) =>
a -> Bool
isAdaClass a
ac = forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "symbol" a => a
#symbol a
ac forall a. Eq a => a -> a -> Bool
== CurrencySymbol
s' Bool -> Bool -> Bool
&& forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name a
ac forall a. Eq a => a -> a -> Bool
== TokenName
n'
  where
    (Tagged (AssetClass CurrencySymbol
s' TokenName
n')) = Tagged "Ada" AssetClass
adaClass

{- | The 'PCurrencySymbol' for Ada, corresponding to an empty string.

 @since 3.9.0
-}
adaSymbolData :: forall (s :: S). Term s (PAsData PCurrencySymbol)
adaSymbolData :: forall (s :: S). Term s (PAsData PCurrencySymbol)
adaSymbolData = forall (p :: PType) h (s :: S).
(ToData h, PLifted p ~ h, PConstanted h ~ p) =>
h -> Term s (PAsData p)
pconstantData CurrencySymbol
""

{- | The 'AssetClass' for Ada, corresponding to an empty currency symbol and
 token name.

 @since 3.9.0
-}
adaClass :: Tagged "Ada" AssetClass
adaClass :: Tagged "Ada" AssetClass
adaClass = forall {k} (s :: k) b. b -> Tagged s b
Tagged forall a b. (a -> b) -> a -> b
$ CurrencySymbol -> TokenName -> AssetClass
AssetClass CurrencySymbol
"" TokenName
""

{- | Plutarch equivalent for 'adaClass'.

 @since 3.9.0
-}
padaClass :: forall (s :: S). Term s (PTagged "Ada" PAssetClass)
padaClass :: forall (s :: S). Term s (PTagged "Ada" PAssetClass)
padaClass = forall {k} (unit :: k) (s :: S).
Tagged unit AssetClass -> Term s (PTagged unit PAssetClass)
pconstantClassT Tagged "Ada" AssetClass
adaClass

{- | The empty 'PTokenName'

 @since 3.9.0
-}
emptyTokenNameData :: forall (s :: S). Term s (PAsData PTokenName)
emptyTokenNameData :: forall (s :: S). Term s (PAsData PTokenName)
emptyTokenNameData = forall (p :: PType) h (s :: S).
(ToData h, PLifted p ~ h, PConstanted h ~ p) =>
h -> Term s (PAsData p)
pconstantData TokenName
""

----------------------------------------
-- Data-Encoded version

{- | A 'PlutusTx.Data'-encoded version of 'AssetClass', without the currency
 tag.

 @since 3.10.0
-}
newtype PAssetClassData (s :: S)
  = PAssetClassData
      ( Term
          s
          ( PDataRecord
              '[ "symbol" ':= PCurrencySymbol
               , "name" ':= PTokenName
               ]
          )
      )
  deriving stock
    ( -- | @since 3.9.0
      forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x. Rep (PAssetClassData s) x -> PAssetClassData s
forall (s :: S) x. PAssetClassData s -> Rep (PAssetClassData s) x
$cto :: forall (s :: S) x. Rep (PAssetClassData s) x -> PAssetClassData s
$cfrom :: forall (s :: S) x. PAssetClassData s -> Rep (PAssetClassData s) x
Generic
    )
  deriving anyclass
    ( -- | @since 3.9.0
      forall (s :: S).
PAssetClassData s -> Term s (PInner PAssetClassData)
forall (s :: S) (b :: PType).
Term s (PInner PAssetClassData)
-> (PAssetClassData s -> Term s b) -> Term s b
forall (a :: PType).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: PType).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
pmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PAssetClassData)
-> (PAssetClassData s -> Term s b) -> Term s b
$cpmatch' :: forall (s :: S) (b :: PType).
Term s (PInner PAssetClassData)
-> (PAssetClassData s -> Term s b) -> Term s b
pcon' :: forall (s :: S).
PAssetClassData s -> Term s (PInner PAssetClassData)
$cpcon' :: forall (s :: S).
PAssetClassData s -> Term s (PInner PAssetClassData)
PlutusType
    , -- | @since 3.9.0
      forall (s :: S).
Term s PAssetClassData -> Term s PAssetClassData -> Term s PBool
forall (t :: PType).
(forall (s :: S). Term s t -> Term s t -> Term s PBool) -> PEq t
#== :: forall (s :: S).
Term s PAssetClassData -> Term s PAssetClassData -> Term s PBool
$c#== :: forall (s :: S).
Term s PAssetClassData -> Term s PAssetClassData -> Term s PBool
PEq
    , -- | @since 3.9.0
      forall (s :: S).
Term s (PAsData PAssetClassData) -> Term s PAssetClassData
forall (s :: S). Term s PAssetClassData -> Term s PData
forall (a :: PType).
(forall (s :: S). Term s (PAsData a) -> Term s a)
-> (forall (s :: S). Term s a -> Term s PData) -> PIsData a
pdataImpl :: forall (s :: S). Term s PAssetClassData -> Term s PData
$cpdataImpl :: forall (s :: S). Term s PAssetClassData -> Term s PData
pfromDataImpl :: forall (s :: S).
Term s (PAsData PAssetClassData) -> Term s PAssetClassData
$cpfromDataImpl :: forall (s :: S).
Term s (PAsData PAssetClassData) -> Term s PAssetClassData
PIsData
    , -- | @since 3.9.0
      forall (s :: S).
Term s PAssetClassData
-> Term s (PDataRecord (PFields PAssetClassData))
forall (a :: PType).
(forall (s :: S). Term s a -> Term s (PDataRecord (PFields a)))
-> PDataFields a
ptoFields :: forall (s :: S).
Term s PAssetClassData
-> Term s (PDataRecord (PFields PAssetClassData))
$cptoFields :: forall (s :: S).
Term s PAssetClassData
-> Term s (PDataRecord (PFields PAssetClassData))
PDataFields
    , -- | @since 3.9.0
      forall (s :: S). Bool -> Term s PAssetClassData -> Term s PString
forall (t :: PType).
(forall (s :: S). Bool -> Term s t -> Term s PString) -> PShow t
pshow' :: forall (s :: S). Bool -> Term s PAssetClassData -> Term s PString
$cpshow' :: forall (s :: S). Bool -> Term s PAssetClassData -> Term s PString
PShow
    )

-- | @since 3.10.0
instance DerivePlutusType PAssetClassData where
  type DPTStrat _ = PlutusTypeNewtype

-- | @since 3.10.0
instance Plutarch.Lift.PUnsafeLiftDecl PAssetClassData where
  type PLifted PAssetClassData = AssetClass

-- | @since 3.21.3
instance PTryFrom PData (PAsData PAssetClassData)

-- | @since 3.10.0
passetClassData ::
  forall (s :: S).
  Term s (PCurrencySymbol :--> PTokenName :--> PAssetClassData)
passetClassData :: forall (s :: S).
Term s (PCurrencySymbol :--> (PTokenName :--> PAssetClassData))
passetClassData = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PCurrencySymbol
sym Term s PTokenName
tk ->
    forall (r :: [PLabeledType]) (s :: S) (pt :: PType).
PlutusType pt =>
(forall (s' :: S). Term s' (PDataRecord r) -> pt s')
-> RecordMorphism s '[] r -> Term s pt
mkRecordConstr
      forall (s :: S).
Term
  s
  (PDataRecord
     '[ "symbol" ':= PCurrencySymbol, "name" ':= PTokenName])
-> PAssetClassData s
PAssetClassData
      ( forall a. IsLabel "symbol" a => a
#symbol
          forall (sym :: Symbol) (a :: PType) (as :: [PLabeledType])
       (s :: S).
FieldName sym
-> Term s (PAsData a) -> RecordMorphism s as ((sym ':= a) : as)
.= forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s PCurrencySymbol
sym
          forall (s :: S) (a :: [PLabeledType]) (b :: [PLabeledType])
       (c :: [PLabeledType]).
RecordMorphism s b c
-> RecordMorphism s a b -> RecordMorphism s a c
.& forall a. IsLabel "name" a => a
#name
          forall (sym :: Symbol) (a :: PType) (as :: [PLabeledType])
       (s :: S).
FieldName sym
-> Term s (PAsData a) -> RecordMorphism s as ((sym ':= a) : as)
.= forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s PTokenName
tk
      )

-- | @since 3.10.4
passetClassDataT ::
  forall {k :: Type} (unit :: k) (s :: S).
  Term s (PCurrencySymbol :--> PTokenName :--> PTagged unit PAssetClassData)
passetClassDataT :: forall {k} (unit :: k) (s :: S).
Term
  s
  (PCurrencySymbol
   :--> (PTokenName :--> PTagged unit PAssetClassData))
passetClassDataT = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PCurrencySymbol
sym Term s PTokenName
tk ->
    forall (f :: PType -> PType) (a :: PType) (s :: S).
(PApplicative f, PSubcategory f a) =>
Term s (a :--> f a)
ppure forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (s :: S).
Term s (PCurrencySymbol :--> (PTokenName :--> PAssetClassData))
passetClassData forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s PCurrencySymbol
sym forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s PTokenName
tk

{- | Convert from 'PAssetClassData' to 'PAssetClass'.

 @since 3.10.4
-}
ptoScottEncoding ::
  forall (s :: S).
  Term s (PAssetClassData :--> PAssetClass)
ptoScottEncoding :: forall (s :: S). Term s (PAssetClassData :--> PAssetClass)
ptoScottEncoding = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PAssetClassData
cls ->
    forall (fs :: [Symbol]) (a :: PType) (s :: S) (b :: PType)
       (ps :: [PLabeledType]) (bs :: [ToBind]).
(PDataFields a, ps ~ PFields a, bs ~ Bindings ps fs,
 BindFields ps bs) =>
Term s a -> (HRecOf a fs s -> Term s b) -> Term s b
pletFields @["symbol", "name"] Term s PAssetClassData
cls forall a b. (a -> b) -> a -> b
$
      \HRecOf PAssetClassData '["symbol", "name"] s
cls' ->
        forall (a :: PType) (s :: S). PlutusType a => a s -> Term s a
pcon forall a b. (a -> b) -> a -> b
$
          forall (s :: S).
Term s (PAsData PCurrencySymbol)
-> Term s (PAsData PTokenName) -> PAssetClass s
PAssetClass
            (forall {k} (x :: k) r a. HasField x r a => r -> a
getField @"symbol" HRecOf PAssetClassData '["symbol", "name"] s
cls')
            (forall {k} (x :: k) r a. HasField x r a => r -> a
getField @"name" HRecOf PAssetClassData '["symbol", "name"] s
cls')

{- | Convert from 'PAssetClass' to 'PAssetClassData'.

 @since 3.10.4
-}
pfromScottEncoding ::
  forall (s :: S).
  Term s (PAssetClass :--> PAssetClassData)
pfromScottEncoding :: forall (s :: S). Term s (PAssetClass :--> PAssetClassData)
pfromScottEncoding = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PAssetClass
cls -> forall (a :: PType) (s :: S) (b :: PType).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch Term s PAssetClass
cls forall a b. (a -> b) -> a -> b
$
    \(PAssetClass Term s (PAsData PCurrencySymbol)
sym Term s (PAsData PTokenName)
tk) ->
      forall (r :: [PLabeledType]) (s :: S) (pt :: PType).
PlutusType pt =>
(forall (s' :: S). Term s' (PDataRecord r) -> pt s')
-> RecordMorphism s '[] r -> Term s pt
mkRecordConstr
        forall (s :: S).
Term
  s
  (PDataRecord
     '[ "symbol" ':= PCurrencySymbol, "name" ':= PTokenName])
-> PAssetClassData s
PAssetClassData
        ( forall a. IsLabel "symbol" a => a
#symbol
            forall (sym :: Symbol) (a :: PType) (as :: [PLabeledType])
       (s :: S).
FieldName sym
-> Term s (PAsData a) -> RecordMorphism s as ((sym ':= a) : as)
.= Term s (PAsData PCurrencySymbol)
sym
            forall (s :: S) (a :: [PLabeledType]) (b :: [PLabeledType])
       (c :: [PLabeledType]).
RecordMorphism s b c
-> RecordMorphism s a b -> RecordMorphism s a c
.& forall a. IsLabel "name" a => a
#name
            forall (sym :: Symbol) (a :: PType) (as :: [PLabeledType])
       (s :: S).
FieldName sym
-> Term s (PAsData a) -> RecordMorphism s as ((sym ':= a) : as)
.= Term s (PAsData PTokenName)
tk
        )

{- | Wrap a function using the Scott-encoded 'PAssetClass' to one using the
 'PlutusTx.Data'-encoded version.

 @since 3.10.4
-}
pviaScottEncoding ::
  forall (a :: PType).
  ClosedTerm (PAssetClass :--> a) ->
  ClosedTerm (PAssetClassData :--> a)
pviaScottEncoding :: forall (a :: PType).
ClosedTerm (PAssetClass :--> a)
-> ClosedTerm (PAssetClassData :--> a)
pviaScottEncoding ClosedTerm (PAssetClass :--> a)
fn = forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic forall a b. (a -> b) -> a -> b
$
  forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
plam forall a b. (a -> b) -> a -> b
$ \Term s PAssetClassData
cls ->
    ClosedTerm (PAssetClass :--> a)
fn forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
#$ forall (s :: S). Term s (PAssetClassData :--> PAssetClass)
ptoScottEncoding forall (s :: S) (a :: PType) (b :: PType).
HasCallStack =>
Term s (a :--> b) -> Term s a -> Term s b
# Term s PAssetClassData
cls

{- | Version of 'assetClassValue' for tagged 'AssetClass' and 'Tagged'.

 @since 3.10.4
-}
assetClassValue ::
  forall {k :: Type} (unit :: k).
  Tagged unit AssetClass ->
  Tagged unit Integer ->
  Value.Value
assetClassValue :: forall {k} (unit :: k).
Tagged unit AssetClass -> Tagged unit Integer -> Value
assetClassValue (Tagged (AssetClass CurrencySymbol
sym TokenName
tk)) Tagged unit Integer
q =
  CurrencySymbol -> TokenName -> Integer -> Value
Value.singleton CurrencySymbol
sym TokenName
tk forall a b. (a -> b) -> a -> b
$ forall {k} (s :: k) b. Tagged s b -> b
untag Tagged unit Integer
q

----------------------------------------
-- Field Labels

-- | @since 3.9.0
makeFieldLabelsNoPrefix ''PAssetClass

-- | @since 3.9.0
makeFieldLabelsNoPrefix ''AssetClass

-- | @since 3.10.2
instance
  (k ~ A_Lens, a ~ CurrencySymbol, b ~ CurrencySymbol, tag ~ tag') =>
  LabelOptic "symbol" k (Tagged tag AssetClass) (Tagged tag' AssetClass) a b
  where
  labelOptic :: Optic k '[] (Tagged tag AssetClass) (Tagged tag' AssetClass) a b
labelOptic = forall a. IsLabel "unTagged" a => a
#unTagged forall k (is :: [Type]) (js :: [Type]) (ks :: [Type]) s t u v a b.
AppendIndices is js ks =>
Optic k is s t u v -> Optic k js u v a b -> Optic k ks s t a b
%% forall a. IsLabel "symbol" a => a
#symbol

-- | @since 3.10.2
instance
  (k ~ A_Lens, a ~ TokenName, b ~ TokenName, tag ~ tag') =>
  LabelOptic "name" k (Tagged tag AssetClass) (Tagged tag' AssetClass) a b
  where
  labelOptic :: Optic k '[] (Tagged tag AssetClass) (Tagged tag' AssetClass) a b
labelOptic = forall a. IsLabel "unTagged" a => a
#unTagged forall k (is :: [Type]) (js :: [Type]) (ks :: [Type]) s t u v a b.
AppendIndices is js ks =>
Optic k is s t u v -> Optic k js u v a b -> Optic k ks s t a b
%% forall a. IsLabel "name" a => a
#name

----------------------------------------
-- Ply instances

-- | @since 3.10.4
instance PlyArg AssetClass where
  type UPLCRep AssetClass = [PlutusTx.Data]
  toBuiltinArg :: AssetClass -> UPLCRep AssetClass
toBuiltinArg AssetClass
ac =
    case forall a. ToData a => a -> Data
PlutusTx.toData @AssetClass AssetClass
ac of
      PlutusTx.List [Data]
x -> [Data]
x
      Data
_ -> forall a. HasCallStack => String -> a
error String
"unreachable"
  toBuiltinArgData :: ToDataConstraint AssetClass => AssetClass -> Data
toBuiltinArgData = forall a. ToData a => a -> Data
PlutusTx.toData

-- | @since 3.10.4
type instance PlyArgOf PAssetClassData = AssetClass

{- | Type-level marker to indicate whether a 'GenAssetClass' can have the ADA
 'AssetClass' inside it or not.

 @since 3.11.1
-}
data AdaClassPresence = WithAdaClass | WithoutAdaClass
  deriving stock
    ( -- | @since 3.10.5
      AdaClassPresence -> AdaClassPresence -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AdaClassPresence -> AdaClassPresence -> Bool
$c/= :: AdaClassPresence -> AdaClassPresence -> Bool
== :: AdaClassPresence -> AdaClassPresence -> Bool
$c== :: AdaClassPresence -> AdaClassPresence -> Bool
Eq
    , -- | @since 3.10.5
      Int -> AdaClassPresence -> ShowS
[AdaClassPresence] -> ShowS
AdaClassPresence -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AdaClassPresence] -> ShowS
$cshowList :: [AdaClassPresence] -> ShowS
show :: AdaClassPresence -> String
$cshow :: AdaClassPresence -> String
showsPrec :: Int -> AdaClassPresence -> ShowS
$cshowsPrec :: Int -> AdaClassPresence -> ShowS
Show
    , -- | @since 3.10.5
      Eq AdaClassPresence
AdaClassPresence -> AdaClassPresence -> Bool
AdaClassPresence -> AdaClassPresence -> Ordering
AdaClassPresence -> AdaClassPresence -> AdaClassPresence
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
min :: AdaClassPresence -> AdaClassPresence -> AdaClassPresence
$cmin :: AdaClassPresence -> AdaClassPresence -> AdaClassPresence
max :: AdaClassPresence -> AdaClassPresence -> AdaClassPresence
$cmax :: AdaClassPresence -> AdaClassPresence -> AdaClassPresence
>= :: AdaClassPresence -> AdaClassPresence -> Bool
$c>= :: AdaClassPresence -> AdaClassPresence -> Bool
> :: AdaClassPresence -> AdaClassPresence -> Bool
$c> :: AdaClassPresence -> AdaClassPresence -> Bool
<= :: AdaClassPresence -> AdaClassPresence -> Bool
$c<= :: AdaClassPresence -> AdaClassPresence -> Bool
< :: AdaClassPresence -> AdaClassPresence -> Bool
$c< :: AdaClassPresence -> AdaClassPresence -> Bool
compare :: AdaClassPresence -> AdaClassPresence -> Ordering
$ccompare :: AdaClassPresence -> AdaClassPresence -> Ordering
Ord
    )

{- | A helper newtype for QuickCheck use with 'AssetClass'es. Has a type-level
 tag to indicate whether it could potentially contain the ADA 'AssetClass'. We
 provide instances of 'Arbitrary', 'CoArbitrary' and 'Function' around this
 newtype, intended to act on the 'AssetClass' inside it.

 The easiest way to use this newtype is by pattern matching:

 > forAll arbitrary $ \((GenAssetClass ac) :: GenAssetClass WithAdaClass) -> ...

 You can also \'re-wrap\' for shrinking:

 > shrink (GenAssetClass ac :: GenAssetClass WithAdaClass)

 = Note

 Due to limitations in QuickCheck itself, 'GenCurrencySymbol' with the
 'WithAdaSymbol' tag over-represents the ADA symbol. We inherit this behaviour
 on all instances of 'GenAssetClass' with th 'WithAdaClass' tag.

 @since 3.11.1
-}
newtype GenAssetClass (p :: AdaClassPresence) = GenAssetClass AssetClass
  deriving
    ( -- | @since 3.10.5
      GenAssetClass p -> GenAssetClass p -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (p :: AdaClassPresence).
GenAssetClass p -> GenAssetClass p -> Bool
/= :: GenAssetClass p -> GenAssetClass p -> Bool
$c/= :: forall (p :: AdaClassPresence).
GenAssetClass p -> GenAssetClass p -> Bool
== :: GenAssetClass p -> GenAssetClass p -> Bool
$c== :: forall (p :: AdaClassPresence).
GenAssetClass p -> GenAssetClass p -> Bool
Eq
    )
    via AssetClass
  deriving stock
    ( -- | @since 3.10.5
      Int -> GenAssetClass p -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (p :: AdaClassPresence). Int -> GenAssetClass p -> ShowS
forall (p :: AdaClassPresence). [GenAssetClass p] -> ShowS
forall (p :: AdaClassPresence). GenAssetClass p -> String
showList :: [GenAssetClass p] -> ShowS
$cshowList :: forall (p :: AdaClassPresence). [GenAssetClass p] -> ShowS
show :: GenAssetClass p -> String
$cshow :: forall (p :: AdaClassPresence). GenAssetClass p -> String
showsPrec :: Int -> GenAssetClass p -> ShowS
$cshowsPrec :: forall (p :: AdaClassPresence). Int -> GenAssetClass p -> ShowS
Show
    )

{- | This instance shrinks only in the 'TokenName', as 'CurrencySymbol's do not
 shrink.

 = Note

 If this would generate the ADA 'AssetClass', its 'TokenName' will be empty.

 @since 3.11.1
-}
instance Arbitrary (GenAssetClass 'WithAdaClass) where
  {-# INLINEABLE arbitrary #-}
  arbitrary :: Gen (GenAssetClass 'WithAdaClass)
arbitrary =
    forall (p :: AdaClassPresence). AssetClass -> GenAssetClass p
GenAssetClass forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> do
      GenCurrencySymbol CurrencySymbol
sym :: GenCurrencySymbol 'WithAdaSymbol <- forall a. Arbitrary a => Gen a
arbitrary
      let Value.CurrencySymbol BuiltinByteString
inner = CurrencySymbol
sym
      TokenName
tn <-
        if BuiltinByteString
inner forall a. Eq a => a -> a -> Bool
== BuiltinByteString
""
          then forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. BuiltinByteString -> TokenName
Value.TokenName forall a b. (a -> b) -> a -> b
$ BuiltinByteString
""
          else forall a. Arbitrary a => Gen a
arbitrary
      forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
        AssetClass
          { $sel:symbol:AssetClass :: CurrencySymbol
symbol = CurrencySymbol
sym
          , $sel:name:AssetClass :: TokenName
name = TokenName
tn
          }
  {-# INLINEABLE shrink #-}
  shrink :: GenAssetClass 'WithAdaClass -> [GenAssetClass 'WithAdaClass]
shrink (GenAssetClass AssetClass
ac) =
    forall (p :: AdaClassPresence). AssetClass -> GenAssetClass p
GenAssetClass forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> do
      TokenName
tn' <- forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name forall a b. (a -> b) -> a -> b
$ AssetClass
ac
      forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set forall a. IsLabel "name" a => a
#name TokenName
tn' forall a b. (a -> b) -> a -> b
$ AssetClass
ac

{- | This instance shrinks only in the 'TokenName', as 'CurrencySymbol's do not
 shrink.

 @since 3.11.1
-}
instance Arbitrary (GenAssetClass 'WithoutAdaClass) where
  {-# INLINEABLE arbitrary #-}
  arbitrary :: Gen (GenAssetClass 'WithoutAdaClass)
arbitrary =
    forall (p :: AdaClassPresence). AssetClass -> GenAssetClass p
GenAssetClass forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> do
      GenCurrencySymbol CurrencySymbol
sym :: GenCurrencySymbol 'WithoutAdaSymbol <- forall a. Arbitrary a => Gen a
arbitrary
      TokenName
tn <- forall a. Arbitrary a => Gen a
arbitrary
      forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
        AssetClass
          { $sel:symbol:AssetClass :: CurrencySymbol
symbol = CurrencySymbol
sym
          , $sel:name:AssetClass :: TokenName
name = TokenName
tn
          }
  {-# INLINEABLE shrink #-}
  shrink :: GenAssetClass 'WithoutAdaClass -> [GenAssetClass 'WithoutAdaClass]
shrink (GenAssetClass AssetClass
ac) =
    forall (p :: AdaClassPresence). AssetClass -> GenAssetClass p
GenAssetClass forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> do
      TokenName
tn' <- forall a. Arbitrary a => a -> [a]
shrink forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name forall a b. (a -> b) -> a -> b
$ AssetClass
ac
      forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s t a b.
Is k A_Setter =>
Optic k is s t a b -> b -> s -> t
set forall a. IsLabel "name" a => a
#name TokenName
tn' forall a b. (a -> b) -> a -> b
$ AssetClass
ac

-- | @since 3.11.1
instance CoArbitrary (GenAssetClass 'WithAdaClass) where
  {-# INLINEABLE coarbitrary #-}
  coarbitrary :: forall b. GenAssetClass 'WithAdaClass -> Gen b -> Gen b
coarbitrary (GenAssetClass AssetClass
ac) =
    let GenCurrencySymbol 'WithAdaSymbol
asGen :: GenCurrencySymbol 'WithAdaSymbol =
          forall (p :: AdaSymbolPresence).
CurrencySymbol -> GenCurrencySymbol p
GenCurrencySymbol forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "symbol" a => a
#symbol forall a b. (a -> b) -> a -> b
$ AssetClass
ac
     in forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary GenCurrencySymbol 'WithAdaSymbol
asGen forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary (forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name AssetClass
ac)

-- | @since 3.11.1
instance CoArbitrary (GenAssetClass 'WithoutAdaClass) where
  {-# INLINEABLE coarbitrary #-}
  coarbitrary :: forall b. GenAssetClass 'WithoutAdaClass -> Gen b -> Gen b
coarbitrary (GenAssetClass AssetClass
ac) =
    let GenCurrencySymbol 'WithoutAdaSymbol
asGen :: GenCurrencySymbol 'WithoutAdaSymbol =
          forall (p :: AdaSymbolPresence).
CurrencySymbol -> GenCurrencySymbol p
GenCurrencySymbol forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "symbol" a => a
#symbol forall a b. (a -> b) -> a -> b
$ AssetClass
ac
     in forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary GenCurrencySymbol 'WithoutAdaSymbol
asGen forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. CoArbitrary a => a -> Gen b -> Gen b
coarbitrary (forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name AssetClass
ac)

-- | @since 3.11.1
instance Function (GenAssetClass 'WithAdaClass) where
  {-# INLINEABLE function #-}
  function :: forall b.
(GenAssetClass 'WithAdaClass -> b)
-> GenAssetClass 'WithAdaClass :-> b
function = forall b a c.
Function b =>
(a -> b) -> (b -> a) -> (a -> c) -> a :-> c
functionMap GenAssetClass 'WithAdaClass
-> (GenCurrencySymbol 'WithAdaSymbol, TokenName)
into (GenCurrencySymbol 'WithAdaSymbol, TokenName)
-> GenAssetClass 'WithAdaClass
outOf
    where
      into ::
        GenAssetClass 'WithAdaClass ->
        (GenCurrencySymbol 'WithAdaSymbol, TokenName)
      into :: GenAssetClass 'WithAdaClass
-> (GenCurrencySymbol 'WithAdaSymbol, TokenName)
into (GenAssetClass AssetClass
ac) =
        (forall (p :: AdaSymbolPresence).
CurrencySymbol -> GenCurrencySymbol p
GenCurrencySymbol forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "symbol" a => a
#symbol forall a b. (a -> b) -> a -> b
$ AssetClass
ac, forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name AssetClass
ac)
      outOf ::
        (GenCurrencySymbol 'WithAdaSymbol, TokenName) ->
        GenAssetClass 'WithAdaClass
      outOf :: (GenCurrencySymbol 'WithAdaSymbol, TokenName)
-> GenAssetClass 'WithAdaClass
outOf (GenCurrencySymbol CurrencySymbol
sym, TokenName
tn) =
        forall (p :: AdaClassPresence). AssetClass -> GenAssetClass p
GenAssetClass forall a b. (a -> b) -> a -> b
$
          AssetClass
            { $sel:symbol:AssetClass :: CurrencySymbol
symbol = CurrencySymbol
sym
            , $sel:name:AssetClass :: TokenName
name = TokenName
tn
            }

-- | @since 3.11.1
instance Function (GenAssetClass 'WithoutAdaClass) where
  {-# INLINEABLE function #-}
  function :: forall b.
(GenAssetClass 'WithoutAdaClass -> b)
-> GenAssetClass 'WithoutAdaClass :-> b
function = forall b a c.
Function b =>
(a -> b) -> (b -> a) -> (a -> c) -> a :-> c
functionMap GenAssetClass 'WithoutAdaClass
-> (GenCurrencySymbol 'WithoutAdaSymbol, TokenName)
into (GenCurrencySymbol 'WithoutAdaSymbol, TokenName)
-> GenAssetClass 'WithoutAdaClass
outOf
    where
      into ::
        GenAssetClass 'WithoutAdaClass ->
        (GenCurrencySymbol 'WithoutAdaSymbol, TokenName)
      into :: GenAssetClass 'WithoutAdaClass
-> (GenCurrencySymbol 'WithoutAdaSymbol, TokenName)
into (GenAssetClass AssetClass
ac) =
        (forall (p :: AdaSymbolPresence).
CurrencySymbol -> GenCurrencySymbol p
GenCurrencySymbol forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "symbol" a => a
#symbol forall a b. (a -> b) -> a -> b
$ AssetClass
ac, forall k (is :: [Type]) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view forall a. IsLabel "name" a => a
#name AssetClass
ac)
      outOf ::
        (GenCurrencySymbol 'WithoutAdaSymbol, TokenName) ->
        GenAssetClass 'WithoutAdaClass
      outOf :: (GenCurrencySymbol 'WithoutAdaSymbol, TokenName)
-> GenAssetClass 'WithoutAdaClass
outOf (GenCurrencySymbol CurrencySymbol
sym, TokenName
tn) =
        forall (p :: AdaClassPresence). AssetClass -> GenAssetClass p
GenAssetClass forall a b. (a -> b) -> a -> b
$
          AssetClass
            { $sel:symbol:AssetClass :: CurrencySymbol
symbol = CurrencySymbol
sym
            , $sel:name:AssetClass :: TokenName
name = TokenName
tn
            }