{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-specialise #-}
{-# OPTIONS_GHC -fno-omit-interface-pragmas #-}
module PlutusTx.IsData.Class where
import Prelude qualified as Haskell (Int, error)
import PlutusCore.Data qualified as PLC
import PlutusTx.Base
import PlutusTx.Builtins as Builtins
import PlutusTx.Builtins.Internal (BuiltinData (..))
import PlutusTx.Builtins.Internal qualified as BI
import PlutusTx.Maybe (Maybe (..))
import PlutusTx.Applicative
import PlutusTx.ErrorCodes
import PlutusTx.Trace
import Data.Kind
import Data.Void
import GHC.TypeLits (ErrorMessage (..), TypeError)
class ToData (a :: Type) where
toBuiltinData :: a -> BuiltinData
class FromData (a :: Type) where
fromBuiltinData :: BuiltinData -> Maybe a
class UnsafeFromData (a :: Type) where
unsafeFromBuiltinData :: BuiltinData -> a
instance ToData BuiltinData where
{-# INLINABLE toBuiltinData #-}
toBuiltinData :: BuiltinData -> BuiltinData
toBuiltinData = BuiltinData -> BuiltinData
forall a. a -> a
id
instance FromData BuiltinData where
{-# INLINABLE fromBuiltinData #-}
fromBuiltinData :: BuiltinData -> Maybe BuiltinData
fromBuiltinData BuiltinData
d = BuiltinData -> Maybe BuiltinData
forall a. a -> Maybe a
Just BuiltinData
d
instance UnsafeFromData BuiltinData where
{-# INLINABLE unsafeFromBuiltinData #-}
unsafeFromBuiltinData :: BuiltinData -> BuiltinData
unsafeFromBuiltinData BuiltinData
d = BuiltinData
d
instance (TypeError ('Text "Int is not supported, use Integer instead"))
=> ToData Haskell.Int where
toBuiltinData :: Int -> BuiltinData
toBuiltinData = [Char] -> Int -> BuiltinData
forall a. HasCallStack => [Char] -> a
Haskell.error [Char]
"unsupported"
instance (TypeError ('Text "Int is not supported, use Integer instead"))
=> FromData Haskell.Int where
fromBuiltinData :: BuiltinData -> Maybe Int
fromBuiltinData = [Char] -> BuiltinData -> Maybe Int
forall a. HasCallStack => [Char] -> a
Haskell.error [Char]
"unsupported"
instance (TypeError ('Text "Int is not supported, use Integer instead"))
=> UnsafeFromData Haskell.Int where
unsafeFromBuiltinData :: BuiltinData -> Int
unsafeFromBuiltinData = [Char] -> BuiltinData -> Int
forall a. HasCallStack => [Char] -> a
Haskell.error [Char]
"unsupported"
instance ToData Integer where
{-# INLINABLE toBuiltinData #-}
toBuiltinData :: Integer -> BuiltinData
toBuiltinData Integer
i = Integer -> BuiltinData
mkI Integer
i
instance FromData Integer where
{-# INLINABLE fromBuiltinData #-}
fromBuiltinData :: BuiltinData -> Maybe Integer
fromBuiltinData BuiltinData
d = BuiltinData
-> (Integer -> BuiltinList BuiltinData -> Maybe Integer)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe Integer)
-> (BuiltinList BuiltinData -> Maybe Integer)
-> (Integer -> Maybe Integer)
-> (BuiltinByteString -> Maybe Integer)
-> Maybe Integer
forall r.
BuiltinData
-> (Integer -> BuiltinList BuiltinData -> r)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> r)
-> (BuiltinList BuiltinData -> r)
-> (Integer -> r)
-> (BuiltinByteString -> r)
-> r
matchData' BuiltinData
d (\Integer
_ BuiltinList BuiltinData
_ -> Maybe Integer
forall a. Maybe a
Nothing) (Maybe Integer
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe Integer
forall a b. a -> b -> a
const Maybe Integer
forall a. Maybe a
Nothing) (Maybe Integer -> BuiltinList BuiltinData -> Maybe Integer
forall a b. a -> b -> a
const Maybe Integer
forall a. Maybe a
Nothing) (\Integer
i -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
i) (Maybe Integer -> BuiltinByteString -> Maybe Integer
forall a b. a -> b -> a
const Maybe Integer
forall a. Maybe a
Nothing)
instance UnsafeFromData Integer where
{-# INLINABLE unsafeFromBuiltinData #-}
unsafeFromBuiltinData :: BuiltinData -> Integer
unsafeFromBuiltinData = BuiltinData -> Integer
BI.unsafeDataAsI
instance ToData Builtins.BuiltinByteString where
{-# INLINABLE toBuiltinData #-}
toBuiltinData :: BuiltinByteString -> BuiltinData
toBuiltinData = BuiltinByteString -> BuiltinData
mkB
instance FromData Builtins.BuiltinByteString where
{-# INLINABLE fromBuiltinData #-}
fromBuiltinData :: BuiltinData -> Maybe BuiltinByteString
fromBuiltinData BuiltinData
d = BuiltinData
-> (Integer -> BuiltinList BuiltinData -> Maybe BuiltinByteString)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinByteString)
-> (BuiltinList BuiltinData -> Maybe BuiltinByteString)
-> (Integer -> Maybe BuiltinByteString)
-> (BuiltinByteString -> Maybe BuiltinByteString)
-> Maybe BuiltinByteString
forall r.
BuiltinData
-> (Integer -> BuiltinList BuiltinData -> r)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> r)
-> (BuiltinList BuiltinData -> r)
-> (Integer -> r)
-> (BuiltinByteString -> r)
-> r
matchData' BuiltinData
d (\Integer
_ BuiltinList BuiltinData
_ -> Maybe BuiltinByteString
forall a. Maybe a
Nothing) (Maybe BuiltinByteString
-> BuiltinList (BuiltinPair BuiltinData BuiltinData)
-> Maybe BuiltinByteString
forall a b. a -> b -> a
const Maybe BuiltinByteString
forall a. Maybe a
Nothing) (Maybe BuiltinByteString
-> BuiltinList BuiltinData -> Maybe BuiltinByteString
forall a b. a -> b -> a
const Maybe BuiltinByteString
forall a. Maybe a
Nothing) (Maybe BuiltinByteString -> Integer -> Maybe BuiltinByteString
forall a b. a -> b -> a
const Maybe BuiltinByteString
forall a. Maybe a
Nothing) (\BuiltinByteString
b -> BuiltinByteString -> Maybe BuiltinByteString
forall a. a -> Maybe a
Just BuiltinByteString
b)
instance UnsafeFromData Builtins.BuiltinByteString where
{-# INLINABLE unsafeFromBuiltinData #-}
unsafeFromBuiltinData :: BuiltinData -> BuiltinByteString
unsafeFromBuiltinData = BuiltinData -> BuiltinByteString
BI.unsafeDataAsB
instance ToData a => ToData [a] where
{-# INLINABLE toBuiltinData #-}
toBuiltinData :: [a] -> BuiltinData
toBuiltinData [a]
l = BuiltinList BuiltinData -> BuiltinData
BI.mkList ([a] -> BuiltinList BuiltinData
mapToBuiltin [a]
l)
where
{-# INLINE mapToBuiltin #-}
mapToBuiltin :: [a] -> BI.BuiltinList BI.BuiltinData
mapToBuiltin :: [a] -> BuiltinList BuiltinData
mapToBuiltin = [a] -> BuiltinList BuiltinData
go
where
go :: [a] -> BI.BuiltinList BI.BuiltinData
go :: [a] -> BuiltinList BuiltinData
go [] = BuiltinUnit -> BuiltinList BuiltinData
BI.mkNilData BuiltinUnit
BI.unitval
go (a
x:[a]
xs) = BuiltinData -> BuiltinList BuiltinData -> BuiltinList BuiltinData
forall a. a -> BuiltinList a -> BuiltinList a
BI.mkCons (a -> BuiltinData
forall a. ToData a => a -> BuiltinData
toBuiltinData a
x) ([a] -> BuiltinList BuiltinData
go [a]
xs)
instance FromData a => FromData [a] where
{-# INLINABLE fromBuiltinData #-}
fromBuiltinData :: BuiltinData -> Maybe [a]
fromBuiltinData BuiltinData
d =
BuiltinData
-> (Integer -> BuiltinList BuiltinData -> Maybe [a])
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Maybe [a])
-> (BuiltinList BuiltinData -> Maybe [a])
-> (Integer -> Maybe [a])
-> (BuiltinByteString -> Maybe [a])
-> Maybe [a]
forall r.
BuiltinData
-> (Integer -> BuiltinList BuiltinData -> r)
-> (BuiltinList (BuiltinPair BuiltinData BuiltinData) -> r)
-> (BuiltinList BuiltinData -> r)
-> (Integer -> r)
-> (BuiltinByteString -> r)
-> r
matchData'
BuiltinData
d
(\Integer
_ BuiltinList BuiltinData
_ -> Maybe [a]
forall a. Maybe a
Nothing)
(Maybe [a]
-> BuiltinList (BuiltinPair BuiltinData BuiltinData) -> Maybe [a]
forall a b. a -> b -> a
const Maybe [a]
forall a. Maybe a
Nothing)
BuiltinList BuiltinData -> Maybe [a]
traverseFromBuiltin
(Maybe [a] -> Integer -> Maybe [a]
forall a b. a -> b -> a
const Maybe [a]
forall a. Maybe a
Nothing)
(Maybe [a] -> BuiltinByteString -> Maybe [a]
forall a b. a -> b -> a
const Maybe [a]
forall a. Maybe a
Nothing)
where
{-# INLINE traverseFromBuiltin #-}
traverseFromBuiltin :: BI.BuiltinList BI.BuiltinData -> Maybe [a]
traverseFromBuiltin :: BuiltinList BuiltinData -> Maybe [a]
traverseFromBuiltin = BuiltinList BuiltinData -> Maybe [a]
go
where
go :: BI.BuiltinList BI.BuiltinData -> Maybe [a]
go :: BuiltinList BuiltinData -> Maybe [a]
go BuiltinList BuiltinData
l = BuiltinList BuiltinData
-> (() -> Maybe [a]) -> (() -> Maybe [a]) -> () -> Maybe [a]
forall a b. BuiltinList a -> b -> b -> b
BI.chooseList BuiltinList BuiltinData
l (Maybe [a] -> () -> Maybe [a]
forall a b. a -> b -> a
const ([a] -> Maybe [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [])) (\()
_ -> (a -> [a] -> [a]) -> Maybe a -> Maybe [a] -> Maybe [a]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (:) (BuiltinData -> Maybe a
forall a. FromData a => BuiltinData -> Maybe a
fromBuiltinData (BuiltinList BuiltinData -> BuiltinData
forall a. BuiltinList a -> a
BI.head BuiltinList BuiltinData
l)) (BuiltinList BuiltinData -> Maybe [a]
go (BuiltinList BuiltinData -> BuiltinList BuiltinData
forall a. BuiltinList a -> BuiltinList a
BI.tail BuiltinList BuiltinData
l))) ()
instance UnsafeFromData a => UnsafeFromData [a] where
{-# INLINABLE unsafeFromBuiltinData #-}
unsafeFromBuiltinData :: BuiltinData -> [a]
unsafeFromBuiltinData BuiltinData
d = BuiltinList BuiltinData -> [a]
mapFromBuiltin (BuiltinData -> BuiltinList BuiltinData
BI.unsafeDataAsList BuiltinData
d)
where
{-# INLINE mapFromBuiltin #-}
mapFromBuiltin :: BI.BuiltinList BI.BuiltinData -> [a]
mapFromBuiltin :: BuiltinList BuiltinData -> [a]
mapFromBuiltin = BuiltinList BuiltinData -> [a]
go
where
go :: BI.BuiltinList BI.BuiltinData -> [a]
go :: BuiltinList BuiltinData -> [a]
go BuiltinList BuiltinData
l = BuiltinList BuiltinData -> (() -> [a]) -> (() -> [a]) -> () -> [a]
forall a b. BuiltinList a -> b -> b -> b
BI.chooseList BuiltinList BuiltinData
l ([a] -> () -> [a]
forall a b. a -> b -> a
const []) (\()
_ -> BuiltinData -> a
forall a. UnsafeFromData a => BuiltinData -> a
unsafeFromBuiltinData (BuiltinList BuiltinData -> BuiltinData
forall a. BuiltinList a -> a
BI.head BuiltinList BuiltinData
l) a -> [a] -> [a]
forall a. a -> [a] -> [a]
: BuiltinList BuiltinData -> [a]
go (BuiltinList BuiltinData -> BuiltinList BuiltinData
forall a. BuiltinList a -> BuiltinList a
BI.tail BuiltinList BuiltinData
l)) ()
instance ToData Void where
{-# INLINABLE toBuiltinData #-}
toBuiltinData :: Void -> BuiltinData
toBuiltinData Void
v = Void -> BuiltinData
forall a. Void -> a
absurd Void
v
instance FromData Void where
{-# INLINABLE fromBuiltinData #-}
fromBuiltinData :: BuiltinData -> Maybe Void
fromBuiltinData BuiltinData
_ = Maybe Void
forall a. Maybe a
Nothing
instance UnsafeFromData Void where
{-# INLINABLE unsafeFromBuiltinData #-}
unsafeFromBuiltinData :: BuiltinData -> Void
unsafeFromBuiltinData BuiltinData
_ = BuiltinString -> Void
forall a. BuiltinString -> a
traceError BuiltinString
voidIsNotSupportedError
toData :: (ToData a) => a -> PLC.Data
toData :: a -> Data
toData a
a = BuiltinData -> Data
builtinDataToData (a -> BuiltinData
forall a. ToData a => a -> BuiltinData
toBuiltinData a
a)
fromData :: (FromData a) => PLC.Data -> Maybe a
fromData :: Data -> Maybe a
fromData Data
d = BuiltinData -> Maybe a
forall a. FromData a => BuiltinData -> Maybe a
fromBuiltinData (Data -> BuiltinData
BuiltinData Data
d)