{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
module Cardano.Ledger.Plutus.ToPlutusData where
import Cardano.Ledger.BaseTypes (
BoundedRational (boundRational, unboundRational),
EpochInterval (..),
NonNegativeInterval,
ProtVer (..),
UnitInterval,
)
import Cardano.Ledger.Binary.Version (Version, getVersion, mkVersion)
import Cardano.Ledger.Coin (Coin (..))
import Cardano.Ledger.Plutus.CostModels (
CostModels,
flattenCostModels,
mkCostModelsLenient,
)
import Cardano.Ledger.Plutus.ExUnits (ExUnits (..), Prices (..))
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Ratio ((%))
import Data.Word
import GHC.Real (Ratio ((:%)))
import Numeric.Natural (Natural)
import PlutusLedgerApi.Common (Data (..))
class ToPlutusData x where
toPlutusData :: x -> Data
fromPlutusData :: Data -> Maybe x
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData a => ToPlutusData [a] where
toPlutusData :: [a] -> Data
toPlutusData [a]
xs = [Data] -> Data
List (forall a b. (a -> b) -> [a] -> [b]
map forall x. ToPlutusData x => x -> Data
toPlutusData [a]
xs)
fromPlutusData :: Data -> Maybe [a]
fromPlutusData (List [Data]
xs) = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData [Data]
xs
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance (Ord a, ToPlutusData a, ToPlutusData b) => ToPlutusData (Map a b) where
toPlutusData :: Map a b -> Data
toPlutusData Map a b
m = [(Data, Data)] -> Data
Map forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (\(a
a, b
b) -> (forall x. ToPlutusData x => x -> Data
toPlutusData a
a, forall x. ToPlutusData x => x -> Data
toPlutusData b
b)) (forall k a. Map k a -> [(k, a)]
Map.toAscList Map a b
m)
fromPlutusData :: Data -> Maybe (Map a b)
fromPlutusData (Map [(Data, Data)]
pairs) =
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(Data
k, Data
v) -> (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
k forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
v) [(Data, Data)]
pairs
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData Version where
toPlutusData :: Version -> Data
toPlutusData Version
v = Integer -> Data
I (forall i. Integral i => Version -> i
getVersion @Integer Version
v)
fromPlutusData :: Data -> Maybe Version
fromPlutusData (I Integer
n) = forall i (m :: * -> *). (Integral i, MonadFail m) => i -> m Version
mkVersion @Integer Integer
n
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData ProtVer where
toPlutusData :: ProtVer -> Data
toPlutusData ProtVer
pv = [Data] -> Data
List [forall x. ToPlutusData x => x -> Data
toPlutusData (ProtVer -> Version
pvMajor ProtVer
pv), forall x. ToPlutusData x => x -> Data
toPlutusData (ProtVer -> Natural
pvMinor ProtVer
pv)]
fromPlutusData :: Data -> Maybe ProtVer
fromPlutusData (List [Data
major, Data
minor]) = Version -> Natural -> ProtVer
ProtVer forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
major forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
minor
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData UnitInterval where
toPlutusData :: UnitInterval -> Data
toPlutusData UnitInterval
x = [Data] -> Data
List [Integer -> Data
I Integer
num, Integer -> Data
I Integer
denom]
where
(Integer
num :% Integer
denom) = forall r. BoundedRational r => r -> Ratio Integer
unboundRational UnitInterval
x
fromPlutusData :: Data -> Maybe UnitInterval
fromPlutusData (List [I Integer
num, I Integer
denom]) = forall r. BoundedRational r => Ratio Integer -> Maybe r
boundRational (Integer
num forall a. Integral a => a -> a -> Ratio a
% Integer
denom)
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData NonNegativeInterval where
toPlutusData :: NonNegativeInterval -> Data
toPlutusData NonNegativeInterval
x = [Data] -> Data
List [Integer -> Data
I Integer
num, Integer -> Data
I Integer
denom]
where
(Integer
num :% Integer
denom) = forall r. BoundedRational r => r -> Ratio Integer
unboundRational NonNegativeInterval
x
fromPlutusData :: Data -> Maybe NonNegativeInterval
fromPlutusData (List [I Integer
num, I Integer
denom]) = forall r. BoundedRational r => Ratio Integer -> Maybe r
boundRational (Integer
num forall a. Integral a => a -> a -> Ratio a
% Integer
denom)
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData CostModels where
toPlutusData :: CostModels -> Data
toPlutusData CostModels
costModels = forall x. ToPlutusData x => x -> Data
toPlutusData forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Integral a => a -> Integer
toInteger forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CostModels -> Map Word8 [Int64]
flattenCostModels CostModels
costModels
fromPlutusData :: Data -> Maybe CostModels
fromPlutusData Data
costModelsData = do
Map Word8 [Integer]
costModels :: Map.Map Word8 [Integer] <- forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
costModelsData
forall (m :: * -> *).
MonadFail m =>
Map Word8 [Int64] -> m CostModels
mkCostModelsLenient (forall a b k. (a -> b) -> Map k a -> Map k b
Map.map (forall a b. (a -> b) -> [a] -> [b]
map forall a. Num a => Integer -> a
fromInteger) Map Word8 [Integer]
costModels)
instance ToPlutusData ExUnits where
toPlutusData :: ExUnits -> Data
toPlutusData (ExUnits Natural
a Natural
b) = [Data] -> Data
List [forall x. ToPlutusData x => x -> Data
toPlutusData Natural
a, forall x. ToPlutusData x => x -> Data
toPlutusData Natural
b]
fromPlutusData :: Data -> Maybe ExUnits
fromPlutusData (List [Data
x, Data
y]) = Natural -> Natural -> ExUnits
ExUnits forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
x forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
y
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData Prices where
toPlutusData :: Prices -> Data
toPlutusData Prices
p = [Data] -> Data
List [forall x. ToPlutusData x => x -> Data
toPlutusData (Prices -> NonNegativeInterval
prMem Prices
p), forall x. ToPlutusData x => x -> Data
toPlutusData (Prices -> NonNegativeInterval
prSteps Prices
p)]
fromPlutusData :: Data -> Maybe Prices
fromPlutusData (List [Data
x, Data
y]) = NonNegativeInterval -> NonNegativeInterval -> Prices
Prices forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
x forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall x. ToPlutusData x => Data -> Maybe x
fromPlutusData Data
y
fromPlutusData Data
_ = forall a. Maybe a
Nothing
deriving instance ToPlutusData Coin
instance ToPlutusData Word32 where
toPlutusData :: Word32 -> Data
toPlutusData Word32
w32 = Integer -> Data
I (forall a. Integral a => a -> Integer
toInteger @Word32 Word32
w32)
fromPlutusData :: Data -> Maybe Word32
fromPlutusData (I Integer
n)
| Integer
n forall a. Ord a => a -> a -> Bool
>= Integer
0 Bool -> Bool -> Bool
&& Integer
n forall a. Ord a => a -> a -> Bool
<= forall a. Integral a => a -> Integer
toInteger (forall a. Bounded a => a
maxBound @Word32) =
forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger @Word32 Integer
n
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData Word16 where
toPlutusData :: Word16 -> Data
toPlutusData Word16
w16 = Integer -> Data
I (forall a. Integral a => a -> Integer
toInteger @Word16 Word16
w16)
fromPlutusData :: Data -> Maybe Word16
fromPlutusData (I Integer
n) | Integer
n forall a. Ord a => a -> a -> Bool
>= Integer
0 Bool -> Bool -> Bool
&& Integer
n forall a. Ord a => a -> a -> Bool
<= forall a. Integral a => a -> Integer
toInteger (forall a. Bounded a => a
maxBound @Word16) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger @Word16 Integer
n
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData Word8 where
toPlutusData :: Word8 -> Data
toPlutusData Word8
w8 = Integer -> Data
I (forall a. Integral a => a -> Integer
toInteger @Word8 Word8
w8)
fromPlutusData :: Data -> Maybe Word8
fromPlutusData (I Integer
n) | Integer
n forall a. Ord a => a -> a -> Bool
>= Integer
0 Bool -> Bool -> Bool
&& Integer
n forall a. Ord a => a -> a -> Bool
<= forall a. Integral a => a -> Integer
toInteger (forall a. Bounded a => a
maxBound @Word8) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger @Word8 Integer
n
fromPlutusData Data
_ = forall a. Maybe a
Nothing
deriving instance ToPlutusData EpochInterval
instance ToPlutusData Natural where
toPlutusData :: Natural -> Data
toPlutusData Natural
nat = Integer -> Data
I (forall a. Integral a => a -> Integer
toInteger @Natural Natural
nat)
fromPlutusData :: Data -> Maybe Natural
fromPlutusData (I Integer
n) | Integer
n forall a. Ord a => a -> a -> Bool
>= Integer
0 = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger @Natural Integer
n
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData Integer where
toPlutusData :: Integer -> Data
toPlutusData Integer
n = Integer -> Data
I Integer
n
fromPlutusData :: Data -> Maybe Integer
fromPlutusData (I Integer
n) = forall a. a -> Maybe a
Just Integer
n
fromPlutusData Data
_ = forall a. Maybe a
Nothing
instance ToPlutusData Word where
toPlutusData :: Word -> Data
toPlutusData Word
w = Integer -> Data
I (forall a. Integral a => a -> Integer
toInteger @Word Word
w)
fromPlutusData :: Data -> Maybe Word
fromPlutusData (I Integer
n) | Integer
n forall a. Ord a => a -> a -> Bool
>= Integer
0 Bool -> Bool -> Bool
&& Integer
n forall a. Ord a => a -> a -> Bool
<= forall a. Integral a => a -> Integer
toInteger (forall a. Bounded a => a
maxBound @Word) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger @Word Integer
n
fromPlutusData Data
_ = forall a. Maybe a
Nothing