module Utils (
  pscriptHashToCurrencySymbol,
  pmember,
  pcheck,
)
where

import Plutarch.LedgerApi.V2 (
  PCurrencySymbol,
  PMap,
  PScriptHash,
 )
import Plutarch.Unsafe (punsafeCoerce)

-- | Convert a `ScriptHash` to a `CurrencySymbol`, which has the same representation
pscriptHashToCurrencySymbol :: Term s PScriptHash -> Term s PCurrencySymbol
pscriptHashToCurrencySymbol :: forall (s :: S). Term s PScriptHash -> Term s PCurrencySymbol
pscriptHashToCurrencySymbol = Term s PScriptHash -> Term s PCurrencySymbol
forall (s :: S) (a :: PType) (b :: PType). Term s a -> Term s b
punsafeCoerce

-- TODO (OPTIMIZE): this can be turned into partial `phasMember` and `placksMember` variants
pmember :: (PIsData k) => Term s (k :--> PMap any k v :--> PBool)
pmember :: forall (k :: PType) (s :: S) (any :: KeyGuarantees) (v :: PType).
PIsData k =>
Term s (k :--> (PMap any k v :--> PBool))
pmember = ClosedTerm (k :--> (PMap any k v :--> PBool))
-> Term s (k :--> (PMap any k v :--> PBool))
forall (a :: PType) (s :: S).
HasCallStack =>
ClosedTerm a -> Term s a
phoistAcyclic (ClosedTerm (k :--> (PMap any k v :--> PBool))
 -> Term s (k :--> (PMap any k v :--> PBool)))
-> ClosedTerm (k :--> (PMap any k v :--> PBool))
-> Term s (k :--> (PMap any k v :--> PBool))
forall a b. (a -> b) -> a -> b
$
  (Term s k -> Term s (PMap any k v) -> Term s PBool)
-> Term s (k :--> (PMap any k v :--> PBool))
forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
forall (c :: PType).
HasCallStack =>
(Term s c -> Term s (PMap any k v) -> Term s PBool)
-> Term s (c :--> (PMap any k v :--> PBool))
plam ((Term s k -> Term s (PMap any k v) -> Term s PBool)
 -> Term s (k :--> (PMap any k v :--> PBool)))
-> (Term s k -> Term s (PMap any k v) -> Term s PBool)
-> Term s (k :--> (PMap any k v :--> PBool))
forall a b. (a -> b) -> a -> b
$ \Term s k
key Term s (PMap any k v)
m ->
    (Term
   s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
 -> Term s (PBuiltinPair (PAsData k) (PAsData v))
 -> Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
 -> Term s PBool)
-> (Term
      s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
    -> Term s PBool)
-> Term
     s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
forall (list :: PType -> PType) (a :: PType) (s :: S) (r :: PType).
PIsListLike list a =>
(Term s (list a :--> r) -> Term s a -> Term s (list a) -> Term s r)
-> (Term s (list a :--> r) -> Term s r) -> Term s (list a :--> r)
precList
      ( \Term
  s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
self Term s (PBuiltinPair (PAsData k) (PAsData v))
x Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
xs ->
          Term s PBool -> Term s PBool -> Term s PBool -> Term s PBool
forall (s :: S) (a :: PType).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
            (Term s (PBuiltinPair (PAsData k) (PAsData v) :--> PAsData k)
forall (s :: S) (a :: PType) (b :: PType).
Term s (PBuiltinPair a b :--> a)
pfstBuiltin Term s (PBuiltinPair (PAsData k) (PAsData v) :--> PAsData k)
-> Term s (PBuiltinPair (PAsData k) (PAsData v))
-> Term s (PAsData k)
forall (s :: S) (a :: PType) (b :: PType).
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinPair (PAsData k) (PAsData v))
x Term s (PAsData k) -> Term s (PAsData k) -> Term s PBool
forall (s :: S).
Term s (PAsData k) -> Term s (PAsData k) -> Term s PBool
forall (t :: PType) (s :: S).
PEq t =>
Term s t -> Term s t -> Term s PBool
#== Term s k -> Term s (PAsData k)
forall (a :: PType) (s :: S).
PIsData a =>
Term s a -> Term s (PAsData a)
pdata Term s k
key)
            (PLifted PBool -> Term s PBool
forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant Bool
PLifted PBool
True)
            (Term
  s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
self Term
  s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
-> Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
-> Term s PBool
forall (s :: S) (a :: PType) (b :: PType).
Term s (a :--> b) -> Term s a -> Term s b
# Term s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)))
xs)
      )
      (Term s PBool
-> Term
     s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
-> Term s PBool
forall a b. a -> b -> a
const (Term s PBool
 -> Term
      s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
 -> Term s PBool)
-> Term s PBool
-> Term
     s (PBuiltinList (PBuiltinPair (PAsData k) (PAsData v)) :--> PBool)
-> Term s PBool
forall a b. (a -> b) -> a -> b
$ PLifted PBool -> Term s PBool
forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant Bool
PLifted PBool
False)
      # pto m

pcheck ::
  forall (s :: S).
  Term s PBool ->
  Term s POpaque
pcheck :: forall (s :: S). Term s PBool -> Term s POpaque
pcheck Term s PBool
b =
  Term s PBool -> Term s POpaque -> Term s POpaque -> Term s POpaque
forall (s :: S) (a :: PType).
Term s PBool -> Term s a -> Term s a -> Term s a
pif
    Term s PBool
b
    (Term s (PUnit @S) -> Term s POpaque
forall (s :: S) (a :: PType). Term s a -> Term s POpaque
popaque (Term s (PUnit @S) -> Term s POpaque)
-> Term s (PUnit @S) -> Term s POpaque
forall a b. (a -> b) -> a -> b
$ PLifted (PUnit @S) -> Term s (PUnit @S)
forall (p :: PType) (s :: S). PLift p => PLifted p -> Term s p
pconstant ())
    Term s POpaque
forall (s :: S) (a :: PType). Term s a
perror