module Plutarch.LedgerApi.V1.MintValue (
  PMintValue,
  pemptyMintValue,
  psingletonMintValue,
  ptoMintValue,
) where

import GHC.Generics (Generic)
import Generics.SOP qualified as SOP
import Plutarch.LedgerApi.AssocMap qualified as AssocMap
import Plutarch.LedgerApi.Value (
  PSortedValue,
  pforgetSorted,
  phasZeroAdaEntry,
  phasZeroTokenQuantities,
  pinsertAdaEntry,
  pnormalizeNoAdaNonZeroTokens,
  psingletonSortedValue,
 )
import Plutarch.LedgerApi.Value.CurrencySymbol (PCurrencySymbol, padaSymbol, padaSymbolData)
import Plutarch.LedgerApi.Value.TokenName (PTokenName, padaToken)
import Plutarch.Prelude hiding (psingleton)
import Plutarch.Unsafe (punsafeDowncast)
import PlutusTx.Prelude qualified as PlutusTx

{- | Represents sorted, well-formed Values with a mandatory /zero/ Ada entry,
while all other token quantities must be non-zero.

Duplicate currency symbols or duplicate token names within the same
token map are not allowed (since wip).

@since 3.5.0
-}
newtype PMintValue (s :: S) = PMintValue (Term s PSortedValue)
  deriving stock
    ( -- | @since 3.5.0
      (forall x. PMintValue s -> Rep (PMintValue s) x)
-> (forall x. Rep (PMintValue s) x -> PMintValue s)
-> Generic (PMintValue s)
forall x. Rep (PMintValue s) x -> PMintValue s
forall x. PMintValue s -> Rep (PMintValue s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x. Rep (PMintValue s) x -> PMintValue s
forall (s :: S) x. PMintValue s -> Rep (PMintValue s) x
$cfrom :: forall (s :: S) x. PMintValue s -> Rep (PMintValue s) x
from :: forall x. PMintValue s -> Rep (PMintValue s) x
$cto :: forall (s :: S) x. Rep (PMintValue s) x -> PMintValue s
to :: forall x. Rep (PMintValue s) x -> PMintValue s
Generic
    )
  deriving anyclass
    ( -- | @since 3.5.0
      All SListI (Code (PMintValue s))
All SListI (Code (PMintValue s)) =>
(PMintValue s -> Rep (PMintValue s))
-> (Rep (PMintValue s) -> PMintValue s) -> Generic (PMintValue s)
Rep (PMintValue s) -> PMintValue s
PMintValue s -> Rep (PMintValue s)
forall a.
All SListI (Code a) =>
(a -> Rep a) -> (Rep a -> a) -> Generic a
forall (s :: S). All SListI (Code (PMintValue s))
forall (s :: S). Rep (PMintValue s) -> PMintValue s
forall (s :: S). PMintValue s -> Rep (PMintValue s)
$cfrom :: forall (s :: S). PMintValue s -> Rep (PMintValue s)
from :: PMintValue s -> Rep (PMintValue s)
$cto :: forall (s :: S). Rep (PMintValue s) -> PMintValue s
to :: Rep (PMintValue s) -> PMintValue s
SOP.Generic
    , -- | @since 3.5.0
      (forall (s :: S). Term s (PAsData PMintValue) -> Term s PMintValue)
-> (forall (s :: S). Term s PMintValue -> Term s PData)
-> PIsData PMintValue
forall (s :: S). Term s (PAsData PMintValue) -> Term s PMintValue
forall (s :: S). Term s PMintValue -> Term s PData
forall (a :: S -> Type).
(forall (s :: S). Term s (PAsData a) -> Term s a)
-> (forall (s :: S). Term s a -> Term s PData) -> PIsData a
$cpfromDataImpl :: forall (s :: S). Term s (PAsData PMintValue) -> Term s PMintValue
pfromDataImpl :: forall (s :: S). Term s (PAsData PMintValue) -> Term s PMintValue
$cpdataImpl :: forall (s :: S). Term s PMintValue -> Term s PData
pdataImpl :: forall (s :: S). Term s PMintValue -> Term s PData
PIsData
    , -- | @since 3.5.0
      (forall (s :: S). Bool -> Term s PMintValue -> Term s PString)
-> PShow PMintValue
forall (s :: S). Bool -> Term s PMintValue -> Term s PString
forall (t :: S -> Type).
(forall (s :: S). Bool -> Term s t -> Term s PString) -> PShow t
$cpshow' :: forall (s :: S). Bool -> Term s PMintValue -> Term s PString
pshow' :: forall (s :: S). Bool -> Term s PMintValue -> Term s PString
PShow
    )
  deriving
    ( -- | @since 3.5.0
      (forall (s :: S). PMintValue s -> Term s (PInner PMintValue))
-> (forall (s :: S) (b :: S -> Type).
    Term s (PInner PMintValue)
    -> (PMintValue s -> Term s b) -> Term s b)
-> PlutusType PMintValue
forall (s :: S). PMintValue s -> Term s (PInner PMintValue)
forall (s :: S) (b :: S -> Type).
Term s (PInner PMintValue)
-> (PMintValue s -> Term s b) -> Term s b
forall (a :: S -> Type).
(forall (s :: S). a s -> Term s (PInner a))
-> (forall (s :: S) (b :: S -> Type).
    Term s (PInner a) -> (a s -> Term s b) -> Term s b)
-> PlutusType a
$cpcon' :: forall (s :: S). PMintValue s -> Term s (PInner PMintValue)
pcon' :: forall (s :: S). PMintValue s -> Term s (PInner PMintValue)
$cpmatch' :: forall (s :: S) (b :: S -> Type).
Term s (PInner PMintValue)
-> (PMintValue s -> Term s b) -> Term s b
pmatch' :: forall (s :: S) (b :: S -> Type).
Term s (PInner PMintValue)
-> (PMintValue s -> Term s b) -> Term s b
PlutusType
    )
    via (DeriveNewtypePlutusType PMintValue)

-- | @since 3.5.0
instance PEq PMintValue where
  Term s PMintValue
a #== :: forall (s :: S).
Term s PMintValue -> Term s PMintValue -> Term s PBool
#== Term s PMintValue
b = Term s PMintValue -> Term s (PInner PMintValue)
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto Term s PMintValue
a Term s PSortedValue -> Term s PSortedValue -> Term s PBool
forall (s :: S).
Term s PSortedValue -> Term s PSortedValue -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s PMintValue -> Term s (PInner PMintValue)
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto Term s PMintValue
b

-- | @since 3.5.0
instance Semigroup (Term s PMintValue) where
  Term s PMintValue
a <> :: Term s PMintValue -> Term s PMintValue -> Term s PMintValue
<> Term s PMintValue
b = Term s (PSortedValue :--> PMintValue)
forall (s :: S). Term s (PSortedValue :--> PMintValue)
ptoMintValue Term s (PSortedValue :--> PMintValue)
-> Term s PSortedValue -> Term s PMintValue
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
#$ Term s PMintValue -> Term s (PInner PMintValue)
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto Term s PMintValue
a Term s PSortedValue -> Term s PSortedValue -> Term s PSortedValue
forall a. Semigroup a => a -> a -> a
<> Term s PMintValue -> Term s (PInner PMintValue)
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto Term s PMintValue
b

-- | @since 3.5.0
instance PlutusTx.Semigroup (Term s PMintValue) where
  Term s PMintValue
a <> :: Term s PMintValue -> Term s PMintValue -> Term s PMintValue
<> Term s PMintValue
b = Term s (PSortedValue :--> PMintValue)
forall (s :: S). Term s (PSortedValue :--> PMintValue)
ptoMintValue Term s (PSortedValue :--> PMintValue)
-> Term s PSortedValue -> Term s PMintValue
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
#$ Term s PMintValue -> Term s (PInner PMintValue)
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto Term s PMintValue
a Term s PSortedValue -> Term s PSortedValue -> Term s PSortedValue
forall a. Semigroup a => a -> a -> a
<> Term s PMintValue -> Term s (PInner PMintValue)
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto Term s PMintValue
b

-- | @since 3.5.0
instance PSemigroup PMintValue where
  {-# INLINEABLE (#<>) #-}
  #<> :: forall (s :: S).
Term s PMintValue -> Term s PMintValue -> Term s PMintValue
(#<>) = Term s PMintValue -> Term s PMintValue -> Term s PMintValue
forall a. Semigroup a => a -> a -> a
(<>)

-- | @since 3.5.0
instance Monoid (Term s PMintValue) where
  mempty :: Term s PMintValue
mempty = Term s PMintValue
forall (s :: S). Term s PMintValue
pemptyMintValue

-- | @since 3.5.0
instance PlutusTx.Monoid (Term s PMintValue) where
  mempty :: Term s PMintValue
mempty = Term s PMintValue
forall (s :: S). Term s PMintValue
pemptyMintValue

-- | @since 3.5.0
instance PMonoid PMintValue where
  {-# INLINEABLE pmempty #-}
  pmempty :: forall (s :: S). Term s PMintValue
pmempty = Term s PMintValue
forall a. Monoid a => a
mempty

-- | @since 3.5.0
instance PlutusTx.Group (Term s PMintValue) where
  inv :: Term s PMintValue -> Term s PMintValue
inv = Term s (PInner PMintValue) -> Term s PMintValue
Term s PSortedValue -> Term s PMintValue
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s PSortedValue -> Term s PMintValue)
-> (Term s PMintValue -> Term s PSortedValue)
-> Term s PMintValue
-> Term s PMintValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s PSortedValue -> Term s PSortedValue
forall a. Group a => a -> a
PlutusTx.inv (Term s PSortedValue -> Term s PSortedValue)
-> (Term s PMintValue -> Term s PSortedValue)
-> Term s PMintValue
-> Term s PSortedValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s PMintValue -> Term s (PInner PMintValue)
Term s PMintValue -> Term s PSortedValue
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto

-- | @since 3.5.0
instance PTryFrom PData (PAsData PMintValue) where
  ptryFrom' :: forall (s :: S) (r :: S -> Type).
Term s PData
-> ((Term s (PAsData PMintValue),
     Reduce (PTryFromExcess PData (PAsData PMintValue) s))
    -> Term s r)
-> Term s r
ptryFrom' Term s PData
opq = TermCont
  s
  (Term s (PAsData PMintValue),
   Reduce (PTryFromExcess PData (PAsData PMintValue) s))
-> ((Term s (PAsData PMintValue),
     Reduce (PTryFromExcess PData (PAsData PMintValue) s))
    -> Term s r)
-> Term s r
forall (r :: S -> Type) (s :: S) a.
TermCont s a -> (a -> Term s r) -> Term s r
runTermCont (TermCont
   s
   (Term s (PAsData PMintValue),
    Reduce (PTryFromExcess PData (PAsData PMintValue) s))
 -> ((Term s (PAsData PMintValue),
      Reduce (PTryFromExcess PData (PAsData PMintValue) s))
     -> Term s r)
 -> Term s r)
-> TermCont
     s
     (Term s (PAsData PMintValue),
      Reduce (PTryFromExcess PData (PAsData PMintValue) s))
-> ((Term s (PAsData PMintValue),
     Reduce (PTryFromExcess PData (PAsData PMintValue) s))
    -> Term s r)
-> Term s r
forall a b. (a -> b) -> a -> b
$ do
    (Term s (PAsData PSortedValue)
opq', ()
_) <- (((Term s (PAsData PSortedValue), ()) -> Term s r) -> Term s r)
-> TermCont s (Term s (PAsData PSortedValue), ())
forall a (s :: S) (r :: S -> Type).
((a -> Term s r) -> Term s r) -> TermCont s a
tcont ((((Term s (PAsData PSortedValue), ()) -> Term s r) -> Term s r)
 -> TermCont s (Term s (PAsData PSortedValue), ()))
-> (((Term s (PAsData PSortedValue), ()) -> Term s r) -> Term s r)
-> TermCont s (Term s (PAsData PSortedValue), ())
forall a b. (a -> b) -> a -> b
$ forall (b :: S -> Type) (a :: S -> Type) (s :: S) (r :: S -> Type).
PTryFrom a b =>
Term s a
-> ((Term s b, Reduce (PTryFromExcess a b s)) -> Term s r)
-> Term s r
ptryFrom @(PAsData PSortedValue) Term s PData
opq
    Term s PMintValue
unwrapped <- ((Term s PMintValue -> Term s r) -> Term s r)
-> TermCont s (Term s PMintValue)
forall a (s :: S) (r :: S -> Type).
((a -> Term s r) -> Term s r) -> TermCont s a
tcont (((Term s PMintValue -> Term s r) -> Term s r)
 -> TermCont s (Term s PMintValue))
-> (Term s (PAsData PSortedValue)
    -> (Term s PMintValue -> Term s r) -> Term s r)
-> Term s (PAsData PSortedValue)
-> TermCont s (Term s PMintValue)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s PMintValue -> (Term s PMintValue -> Term s r) -> Term s r
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s a -> (Term s a -> Term s b) -> Term s b
plet (Term s PMintValue -> (Term s PMintValue -> Term s r) -> Term s r)
-> (Term s (PAsData PSortedValue) -> Term s PMintValue)
-> Term s (PAsData PSortedValue)
-> (Term s PMintValue -> Term s r)
-> Term s r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s (PSortedValue :--> PMintValue)
-> Term s PSortedValue -> Term s PMintValue
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
papp Term s (PSortedValue :--> PMintValue)
forall (s :: S). Term s (PSortedValue :--> PMintValue)
ptoMintValue (Term s PSortedValue -> Term s PMintValue)
-> (Term s (PAsData PSortedValue) -> Term s PSortedValue)
-> Term s (PAsData PSortedValue)
-> Term s PMintValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s (PAsData PSortedValue) -> Term s PSortedValue
forall (a :: S -> Type) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (Term s (PAsData PSortedValue) -> TermCont s (Term s PMintValue))
-> Term s (PAsData PSortedValue) -> TermCont s (Term s PMintValue)
forall a b. (a -> b) -> a -> b
$ Term s (PAsData PSortedValue)
opq'
    (Term s (PAsData PMintValue), ())
-> TermCont s (Term s (PAsData PMintValue), ())
forall a. a -> TermCont s a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Term s PMintValue -> Term s (PAsData PMintValue)
forall (a :: S -> Type) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s PMintValue
unwrapped, ())

{- | Checks that we have a valid 'PMintValue'. The underlying map must be
sorted, include a zero ADA entry, and contain no empty token maps or non-ADA
tokens with zero quantities.

@since 3.6.0
-}
instance PValidateData PMintValue where
  pwithValidated :: forall (s :: S).
Term s PData -> forall (r :: S -> Type). Term s r -> Term s r
pwithValidated Term s PData
opq Term s r
x =
    Term s PSortedValue
-> (Term s PSortedValue -> Term s r) -> Term s r
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s a -> (Term s a -> Term s b) -> Term s b
plet (Term s (PAsData PSortedValue) -> Term s PSortedValue
forall (a :: S -> Type) (s :: S).
PIsData a =>
Term s (PAsData a) -> Term s a
pfromData (Term s (PAsData PSortedValue) -> Term s PSortedValue)
-> Term s (PAsData PSortedValue) -> Term s PSortedValue
forall a b. (a -> b) -> a -> b
$ forall (a :: S -> Type) (s :: S).
(PIsData a, PValidateData a) =>
Term s PData -> Term s (PAsData a)
pparseData @PSortedValue Term s PData
opq) ((Term s PSortedValue -> Term s r) -> Term s r)
-> (Term s PSortedValue -> Term s r) -> Term s r
forall a b. (a -> b) -> a -> b
$ \Term s PSortedValue
value ->
      Term s PBool -> Term s r -> Term s r -> Term s r
forall (a :: S -> Type) (s :: S).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
        ( (Term s (PBool :--> PBool)
forall (s :: S). Term s (PBool :--> PBool)
pnot Term s (PBool :--> PBool) -> Term s PBool -> Term s PBool
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
#$ Term s (PSortedValue :--> PBool)
forall (s :: S). Term s (PSortedValue :--> PBool)
phasZeroAdaEntry Term s (PSortedValue :--> PBool)
-> Term s PSortedValue -> Term s PBool
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s PSortedValue
value)
            #|| (phasZeroTokenQuantities #$ pforgetSorted $ dropAdaEntry # value)
        )
        Term s r
forall (s :: S) (a :: S -> Type). Term s a
perror
        Term s r
x
    where
      dropAdaEntry :: forall (s :: S). Term s (PSortedValue :--> PSortedValue)
      dropAdaEntry :: forall (s :: S). Term s (PSortedValue :--> PSortedValue)
dropAdaEntry =
        (Term s PSortedValue -> Term s PSortedValue)
-> Term s (PSortedValue :--> PSortedValue)
forall a (b :: S -> Type) (s :: S) (c :: S -> Type).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
forall (c :: S -> Type).
HasCallStack =>
(Term s c -> Term s PSortedValue) -> Term s (c :--> PSortedValue)
plam ((Term s PSortedValue -> Term s PSortedValue)
 -> Term s (PSortedValue :--> PSortedValue))
-> (Term s PSortedValue -> Term s PSortedValue)
-> Term s (PSortedValue :--> PSortedValue)
forall a b. (a -> b) -> a -> b
$ \Term s PSortedValue
value ->
          Term
  s
  (PBuiltinList
     (PBuiltinPair
        (PAsData PCurrencySymbol)
        (PAsData (PSortedMap PTokenName PInteger))))
-> (PBuiltinList
      (PBuiltinPair
         (PAsData PCurrencySymbol)
         (PAsData (PSortedMap PTokenName PInteger)))
      s
    -> Term s PSortedValue)
-> Term s PSortedValue
forall (a :: S -> Type) (s :: S) (b :: S -> Type).
PlutusType a =>
Term s a -> (a s -> Term s b) -> Term s b
pmatch (Term
  s
  (PInner
     (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger)))
-> Term
     s
     (PInner
        (PInner
           (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger))))
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto (Term
   s
   (PInner
      (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger)))
 -> Term
      s
      (PInner
         (PInner
            (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger)))))
-> Term
     s
     (PInner
        (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger)))
-> Term
     s
     (PInner
        (PInner
           (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger))))
forall a b. (a -> b) -> a -> b
$ Term
  s (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger))
-> Term
     s
     (PInner
        (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger)))
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto (Term
   s (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger))
 -> Term
      s
      (PInner
         (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger))))
-> Term
     s (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger))
-> Term
     s
     (PInner
        (PSortedMap PCurrencySymbol (PSortedMap PTokenName PInteger)))
forall a b. (a -> b) -> a -> b
$ Term s PSortedValue -> Term s (PInner PSortedValue)
forall (a :: S -> Type) (s :: S). Term s a -> Term s (PInner a)
pto Term s PSortedValue
value) ((PBuiltinList
    (PBuiltinPair
       (PAsData PCurrencySymbol)
       (PAsData (PSortedMap PTokenName PInteger)))
    s
  -> Term s PSortedValue)
 -> Term s PSortedValue)
-> (PBuiltinList
      (PBuiltinPair
         (PAsData PCurrencySymbol)
         (PAsData (PSortedMap PTokenName PInteger)))
      s
    -> Term s PSortedValue)
-> Term s PSortedValue
forall a b. (a -> b) -> a -> b
$ \case
            PBuiltinList
  (PBuiltinPair
     (PAsData PCurrencySymbol)
     (PAsData (PSortedMap PTokenName PInteger)))
  s
PNil -> Term s PSortedValue
value
            PCons Term
  s
  (PBuiltinPair
     (PAsData PCurrencySymbol)
     (PAsData (PSortedMap PTokenName PInteger)))
_ Term
  s
  (PBuiltinList
     (PBuiltinPair
        (PAsData PCurrencySymbol)
        (PAsData (PSortedMap PTokenName PInteger))))
xs -> Term s (PInner PSortedValue) -> Term s PSortedValue
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s (PInner PSortedValue) -> Term s PSortedValue)
-> Term s (PInner PSortedValue) -> Term s PSortedValue
forall a b. (a -> b) -> a -> b
$ Term s (PInner (PInner PSortedValue))
-> Term s (PInner PSortedValue)
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s (PInner (PInner PSortedValue))
 -> Term s (PInner PSortedValue))
-> Term s (PInner (PInner PSortedValue))
-> Term s (PInner PSortedValue)
forall a b. (a -> b) -> a -> b
$ Term
  s
  (PInner
     (PAssocMap PCurrencySymbol (PSortedMap PTokenName PInteger)))
-> Term
     s (PAssocMap PCurrencySymbol (PSortedMap PTokenName PInteger))
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast Term
  s
  (PInner
     (PAssocMap PCurrencySymbol (PSortedMap PTokenName PInteger)))
Term
  s
  (PBuiltinList
     (PBuiltinPair
        (PAsData PCurrencySymbol)
        (PAsData (PSortedMap PTokenName PInteger))))
xs

{- | Construct an empty 'PMintValue' with a zero Ada entry.

@since 3.6.0
-}
pemptyMintValue :: forall (s :: S). Term s PMintValue
pemptyMintValue :: forall (s :: S). Term s PMintValue
pemptyMintValue = Term s (PInner PMintValue) -> Term s PMintValue
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s (PInner PMintValue) -> Term s PMintValue)
-> Term s (PInner PMintValue) -> Term s PMintValue
forall a b. (a -> b) -> a -> b
$ Term
  s
  (PCurrencySymbol
   :--> (PTokenName :--> (PInteger :--> PSortedValue)))
forall (s :: S).
Term
  s
  (PCurrencySymbol
   :--> (PTokenName :--> (PInteger :--> PSortedValue)))
psingletonSortedValue Term
  s
  (PCurrencySymbol
   :--> (PTokenName :--> (PInteger :--> PSortedValue)))
-> Term s PCurrencySymbol
-> Term s (PTokenName :--> (PInteger :--> PSortedValue))
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s PCurrencySymbol
forall (s :: S). Term s PCurrencySymbol
padaSymbol Term s (PTokenName :--> (PInteger :--> PSortedValue))
-> Term s PTokenName -> Term s (PInteger :--> PSortedValue)
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s PTokenName
forall (s :: S). Term s PTokenName
padaToken Term s (PInteger :--> PSortedValue)
-> Term s PInteger -> Term s PSortedValue
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s PInteger
0

{- | Construct a singleton 'PMintValue' containing only the given quantity of
the given currency, together with a mandatory zero-Ada entry.


= Important note

If the quantity is zero, or if the provided currency symbol is the Ada symbol,
the result is 'mempty' (i.e. a Value with a single zero-Ada entry).

@since 3.6.0
-}
psingletonMintValue ::
  forall (s :: S).
  Term s (PCurrencySymbol :--> PTokenName :--> PInteger :--> PMintValue)
psingletonMintValue :: forall (s :: S).
Term
  s
  (PCurrencySymbol :--> (PTokenName :--> (PInteger :--> PMintValue)))
psingletonMintValue =
  (forall (s :: S).
 Term
   s
   (PCurrencySymbol
    :--> (PTokenName :--> (PInteger :--> PMintValue))))
-> Term
     s
     (PCurrencySymbol :--> (PTokenName :--> (PInteger :--> PMintValue)))
forall (a :: S -> Type) (s :: S).
HasCallStack =>
(forall (s' :: S). Term s' a) -> Term s a
phoistAcyclic ((forall (s :: S).
  Term
    s
    (PCurrencySymbol
     :--> (PTokenName :--> (PInteger :--> PMintValue))))
 -> Term
      s
      (PCurrencySymbol
       :--> (PTokenName :--> (PInteger :--> PMintValue))))
-> (forall (s :: S).
    Term
      s
      (PCurrencySymbol
       :--> (PTokenName :--> (PInteger :--> PMintValue))))
-> Term
     s
     (PCurrencySymbol :--> (PTokenName :--> (PInteger :--> PMintValue)))
forall a b. (a -> b) -> a -> b
$
    (Term s' PCurrencySymbol
 -> Term s' PTokenName -> Term s' PInteger -> Term s' PMintValue)
-> Term
     s'
     (PCurrencySymbol :--> (PTokenName :--> (PInteger :--> PMintValue)))
forall a (b :: S -> Type) (s :: S) (c :: S -> Type).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
forall (c :: S -> Type).
HasCallStack =>
(Term s' c
 -> Term s' PTokenName -> Term s' PInteger -> Term s' PMintValue)
-> Term s' (c :--> (PTokenName :--> (PInteger :--> PMintValue)))
plam ((Term s' PCurrencySymbol
  -> Term s' PTokenName -> Term s' PInteger -> Term s' PMintValue)
 -> Term
      s'
      (PCurrencySymbol
       :--> (PTokenName :--> (PInteger :--> PMintValue))))
-> (Term s' PCurrencySymbol
    -> Term s' PTokenName -> Term s' PInteger -> Term s' PMintValue)
-> Term
     s'
     (PCurrencySymbol :--> (PTokenName :--> (PInteger :--> PMintValue)))
forall a b. (a -> b) -> a -> b
$ \Term s' PCurrencySymbol
symbol Term s' PTokenName
token Term s' PInteger
amount ->
      Term s' PBool
-> Term s' PMintValue -> Term s' PMintValue -> Term s' PMintValue
forall (a :: S -> Type) (s :: S).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
        (Term s' PInteger
amount Term s' PInteger -> Term s' PInteger -> Term s' PBool
forall (s :: S). Term s PInteger -> Term s PInteger -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s' PInteger
0 Term s' PBool -> Term s' PBool -> Term s' PBool
forall (s :: S). Term s PBool -> Term s PBool -> Term s PBool
#|| Term s' PCurrencySymbol
symbol Term s' PCurrencySymbol -> Term s' PCurrencySymbol -> Term s' PBool
forall (s :: S).
Term s PCurrencySymbol -> Term s PCurrencySymbol -> Term s PBool
forall (t :: S -> Type) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s' PCurrencySymbol
forall (s :: S). Term s PCurrencySymbol
padaSymbol)
        Term s' PMintValue
forall a. Monoid a => a
mempty
        -- FIXME: 4 downcasts is ugly
        ( Term s' (PInner PMintValue) -> Term s' PMintValue
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s' (PInner PMintValue) -> Term s' PMintValue)
-> (Term
      s'
      (PBuiltinList
         (PBuiltinPair
            (PAsData PCurrencySymbol)
            (PAsData (PSortedMap PTokenName PInteger))))
    -> Term s' (PInner PMintValue))
-> Term
     s'
     (PBuiltinList
        (PBuiltinPair
           (PAsData PCurrencySymbol)
           (PAsData (PSortedMap PTokenName PInteger))))
-> Term s' PMintValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s' (PInner (PInner PMintValue)) -> Term s' (PInner PMintValue)
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s' (PInner (PInner PMintValue))
 -> Term s' (PInner PMintValue))
-> (Term
      s'
      (PBuiltinList
         (PBuiltinPair
            (PAsData PCurrencySymbol)
            (PAsData (PSortedMap PTokenName PInteger))))
    -> Term s' (PInner (PInner PMintValue)))
-> Term
     s'
     (PBuiltinList
        (PBuiltinPair
           (PAsData PCurrencySymbol)
           (PAsData (PSortedMap PTokenName PInteger))))
-> Term s' (PInner PMintValue)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s' (PInner (PInner (PInner PMintValue)))
-> Term s' (PInner (PInner PMintValue))
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s' (PInner (PInner (PInner PMintValue)))
 -> Term s' (PInner (PInner PMintValue)))
-> (Term
      s'
      (PBuiltinList
         (PBuiltinPair
            (PAsData PCurrencySymbol)
            (PAsData (PSortedMap PTokenName PInteger))))
    -> Term s' (PInner (PInner (PInner PMintValue))))
-> Term
     s'
     (PBuiltinList
        (PBuiltinPair
           (PAsData PCurrencySymbol)
           (PAsData (PSortedMap PTokenName PInteger))))
-> Term s' (PInner (PInner PMintValue))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term s' (PInner (PInner (PInner (PInner PMintValue))))
-> Term s' (PInner (PInner (PInner PMintValue)))
Term
  s'
  (PBuiltinList
     (PBuiltinPair
        (PAsData PCurrencySymbol)
        (PAsData (PSortedMap PTokenName PInteger))))
-> Term s' (PInner (PInner (PInner PMintValue)))
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term
   s'
   (PBuiltinList
      (PBuiltinPair
         (PAsData PCurrencySymbol)
         (PAsData (PSortedMap PTokenName PInteger))))
 -> Term s' PMintValue)
-> Term
     s'
     (PBuiltinList
        (PBuiltinPair
           (PAsData PCurrencySymbol)
           (PAsData (PSortedMap PTokenName PInteger))))
-> Term s' PMintValue
forall a b. (a -> b) -> a -> b
$
            Term
  s'
  (PBuiltinPair
     (PAsData PCurrencySymbol)
     (PAsData (PSortedMap PTokenName PInteger))
   :--> (PBuiltinList
           (PBuiltinPair
              (PAsData PCurrencySymbol)
              (PAsData (PSortedMap PTokenName PInteger)))
         :--> PBuiltinList
                (PBuiltinPair
                   (PAsData PCurrencySymbol)
                   (PAsData (PSortedMap PTokenName PInteger)))))
forall (a :: S -> Type) (s :: S).
PElemConstraint PBuiltinList a =>
Term s (a :--> (PBuiltinList a :--> PBuiltinList a))
forall (list :: (S -> Type) -> S -> Type) (a :: S -> Type)
       (s :: S).
(PListLike list, PElemConstraint list a) =>
Term s (a :--> (list a :--> list a))
pcons
              # (ppairDataBuiltin # padaSymbolData # pdata (AssocMap.psingleton # padaToken # 0))
              # (pcons # (ppairDataBuiltin # pdata symbol #$ pdata (AssocMap.psingleton # token # amount)) # pnil)
        )

{- Convert a 'PSortedValue' to a 'PMintValue', inserting the zero Ada entry
if missing and ensuring non-zero token quantities.

@since 3.5.0
-}
ptoMintValue :: forall (s :: S). Term s (PSortedValue :--> PMintValue)
ptoMintValue :: forall (s :: S). Term s (PSortedValue :--> PMintValue)
ptoMintValue =
  (forall (s :: S). Term s (PSortedValue :--> PMintValue))
-> Term s (PSortedValue :--> PMintValue)
forall (a :: S -> Type) (s :: S).
HasCallStack =>
(forall (s' :: S). Term s' a) -> Term s a
phoistAcyclic ((forall (s :: S). Term s (PSortedValue :--> PMintValue))
 -> Term s (PSortedValue :--> PMintValue))
-> (forall (s :: S). Term s (PSortedValue :--> PMintValue))
-> Term s (PSortedValue :--> PMintValue)
forall a b. (a -> b) -> a -> b
$
    (Term s' PSortedValue -> Term s' PMintValue)
-> Term s' (PSortedValue :--> PMintValue)
forall a (b :: S -> Type) (s :: S) (c :: S -> Type).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
forall (c :: S -> Type).
HasCallStack =>
(Term s' c -> Term s' PMintValue) -> Term s' (c :--> PMintValue)
plam ((Term s' PSortedValue -> Term s' PMintValue)
 -> Term s' (PSortedValue :--> PMintValue))
-> (Term s' PSortedValue -> Term s' PMintValue)
-> Term s' (PSortedValue :--> PMintValue)
forall a b. (a -> b) -> a -> b
$ \Term s' PSortedValue
val ->
      Term s' (PInner PMintValue) -> Term s' PMintValue
forall (s :: S) (a :: S -> Type). Term s (PInner a) -> Term s a
punsafeDowncast (Term s' (PInner PMintValue) -> Term s' PMintValue)
-> Term s' (PInner PMintValue) -> Term s' PMintValue
forall a b. (a -> b) -> a -> b
$
        Term s' (PSortedValue :--> PSortedValue)
forall (s :: S). Term s (PSortedValue :--> PSortedValue)
pinsertAdaEntry Term s' (PSortedValue :--> PSortedValue)
-> Term s' PSortedValue -> Term s' PSortedValue
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
#$ Term s' (PSortedValue :--> PSortedValue)
forall (s :: S). Term s (PSortedValue :--> PSortedValue)
pnormalizeNoAdaNonZeroTokens Term s' (PSortedValue :--> PSortedValue)
-> Term s' PSortedValue -> Term s' PSortedValue
forall (s :: S) (a :: S -> Type) (b :: S -> Type).
Term s (a :--> b) -> Term s a -> Term s b
# Term s' PSortedValue
val