{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase         #-}
{-# LANGUAGE OverloadedStrings  #-}

module PlutusTx.Blueprint.Purpose where

import Prelude

import Data.Aeson (ToJSON (..))
import Data.Aeson qualified as Json
import Data.Text (Text)
import Language.Haskell.TH.Syntax (Lift)

{- |
  As per CIP-57, a validator arguments (redeemer, datum) and validator parameters
  all must specify a purpose that indicates in which context they are used.
-}
data Purpose = Spend | Mint | Withdraw | Publish
  deriving stock (Purpose -> Purpose -> Bool
(Purpose -> Purpose -> Bool)
-> (Purpose -> Purpose -> Bool) -> Eq Purpose
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Purpose -> Purpose -> Bool
== :: Purpose -> Purpose -> Bool
$c/= :: Purpose -> Purpose -> Bool
/= :: Purpose -> Purpose -> Bool
Eq, Eq Purpose
Eq Purpose =>
(Purpose -> Purpose -> Ordering)
-> (Purpose -> Purpose -> Bool)
-> (Purpose -> Purpose -> Bool)
-> (Purpose -> Purpose -> Bool)
-> (Purpose -> Purpose -> Bool)
-> (Purpose -> Purpose -> Purpose)
-> (Purpose -> Purpose -> Purpose)
-> Ord Purpose
Purpose -> Purpose -> Bool
Purpose -> Purpose -> Ordering
Purpose -> Purpose -> Purpose
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 :: Purpose -> Purpose -> Ordering
compare :: Purpose -> Purpose -> Ordering
$c< :: Purpose -> Purpose -> Bool
< :: Purpose -> Purpose -> Bool
$c<= :: Purpose -> Purpose -> Bool
<= :: Purpose -> Purpose -> Bool
$c> :: Purpose -> Purpose -> Bool
> :: Purpose -> Purpose -> Bool
$c>= :: Purpose -> Purpose -> Bool
>= :: Purpose -> Purpose -> Bool
$cmax :: Purpose -> Purpose -> Purpose
max :: Purpose -> Purpose -> Purpose
$cmin :: Purpose -> Purpose -> Purpose
min :: Purpose -> Purpose -> Purpose
Ord, Int -> Purpose -> ShowS
[Purpose] -> ShowS
Purpose -> String
(Int -> Purpose -> ShowS)
-> (Purpose -> String) -> ([Purpose] -> ShowS) -> Show Purpose
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Purpose -> ShowS
showsPrec :: Int -> Purpose -> ShowS
$cshow :: Purpose -> String
show :: Purpose -> String
$cshowList :: [Purpose] -> ShowS
showList :: [Purpose] -> ShowS
Show, (forall (m :: * -> *). Quote m => Purpose -> m Exp)
-> (forall (m :: * -> *). Quote m => Purpose -> Code m Purpose)
-> Lift Purpose
forall t.
(forall (m :: * -> *). Quote m => t -> m Exp)
-> (forall (m :: * -> *). Quote m => t -> Code m t) -> Lift t
forall (m :: * -> *). Quote m => Purpose -> m Exp
forall (m :: * -> *). Quote m => Purpose -> Code m Purpose
$clift :: forall (m :: * -> *). Quote m => Purpose -> m Exp
lift :: forall (m :: * -> *). Quote m => Purpose -> m Exp
$cliftTyped :: forall (m :: * -> *). Quote m => Purpose -> Code m Purpose
liftTyped :: forall (m :: * -> *). Quote m => Purpose -> Code m Purpose
Lift)

instance ToJSON Purpose where
  toJSON :: Purpose -> Value
toJSON = Text -> Value
Json.String (Text -> Value) -> (Purpose -> Text) -> Purpose -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Purpose -> Text
purposeToText

purposeToText :: Purpose -> Text
purposeToText :: Purpose -> Text
purposeToText = \case
  Purpose
Spend    -> Text
"spend"
  Purpose
Mint     -> Text
"mint"
  Purpose
Withdraw -> Text
"withdraw"
  Purpose
Publish  -> Text
"publish"