packages feed

morley-client-0.1.0: test/Test/AsRPC.hs

-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

{-# OPTIONS_GHC -Wno-star-is-type #-}

module Test.AsRPC
  ( unit_Renames_constructors_fields_and_generic_metadata
  , unit_Can_derive_many_instances_at_once
  , unit_Supports_higher_kinded_types
  , unit_Can_derive_instances_with_newtype
  , unit_Can_derive_many_instances_with_newtypes
  , unit_Can_derive_many_instances_with_type_aliases
  ) where

import Data.Typeable ((:~:)(Refl))
import GHC.Generics
import qualified Language.Haskell.TH.Syntax as TH
import Test.Tasty.HUnit (Assertion)

import Lorentz (BigMap, BigMapId, IsoValue(ToT), MText, customGeneric, leftBalanced, ligoLayout)
import Morley.Client.RPC.AsRPC

import Test.Util (shouldCompileIgnoringInstance, shouldCompileTo)

data ExampleStorage a b = ExampleStorage
  { _esField1 :: Integer
  , _esField2 :: [BigMap Integer MText]
  , _esField3 :: a
  }
  deriving stock Generic
  deriving anyclass IsoValue
deriveRPC "ExampleStorage"

unit_Renames_constructors_fields_and_generic_metadata :: Assertion
unit_Renames_constructors_fields_and_generic_metadata = do
  $(deriveRPC "ExampleStorage" >>= TH.lift) `shouldCompileTo`
    [d|
      data ExampleStorageRPC a (b :: k) = ExampleStorageRPC
        { _esField1RPC :: AsRPC Integer
        , _esField2RPC :: AsRPC [BigMap Integer MText]
        , _esField3RPC :: AsRPC a
        }

      type instance AsRPC (ExampleStorage a (b :: k)) = ExampleStorageRPC a (b :: k)
      deriving anyclass instance IsoValue (AsRPC a) => IsoValue (ExampleStorageRPC a (b :: k))

      instance Generic (ExampleStorageRPC a (b :: k))
          where type Rep (ExampleStorageRPC a
                                      (b :: k)) = D1 ('MetaData "ExampleStorageRPC" "Test.AsRPC" "main" 'False)
                                                      (C1 ('MetaCons "ExampleStorageRPC" 'PrefixI 'True)
                                                          ((:*:) (S1 ('MetaSel ('Just "_esField1RPC")
                                                                              'NoSourceUnpackedness
                                                                              'NoSourceStrictness
                                                                              'DecidedStrict)
                                                                    (Rec0 (AsRPC Integer)))
                                                                ((:*:) (S1 ('MetaSel ('Just "_esField2RPC")
                                                                                      'NoSourceUnpackedness
                                                                                      'NoSourceStrictness
                                                                                      'DecidedStrict)
                                                                            (Rec0 (AsRPC ([BigMap Integer
                                                                                                  MText]))))
                                                                        (S1 ('MetaSel ('Just "_esField3RPC")
                                                                                      'NoSourceUnpackedness
                                                                                      'NoSourceStrictness
                                                                                      'DecidedStrict)
                                                                            (Rec0 (AsRPC a))))))
                from (ExampleStorageRPC v0
                                  v1
                                  v2) = M1 (M1 ((:*:) (M1 (K1 v0)) ((:*:) (M1 (K1 v1)) (M1 (K1 v2)))))
                to (M1 (M1 ((:*:) (M1 (K1 v0))
                                  ((:*:) (M1 (K1 v1)) (M1 (K1 v2)))))) = ExampleStorageRPC v0 v1 v2
    |]

data Ex1 = Ex1 Integer Ex1Inner
  deriving stock Generic
  deriving anyclass IsoValue
data Ex1Inner = Ex1Inner Integer
  deriving stock Generic
  deriving anyclass IsoValue

data Ex2 = Ex2 Integer
  deriving stock Generic
  deriving anyclass IsoValue
deriveRPC "Ex2"

data Ex3 = Ex3 Integer
  deriving stock (Generic, Eq, Ord)
  deriving anyclass IsoValue

data Ex4 a = Ex4 a
  deriving stock Generic
  deriving anyclass IsoValue

data ExampleMany = ExampleMany
  { _emField1 :: Integer
  , _emField2 :: Ex1
  , _emField3 :: Ex2
  , _emField4 :: [BigMap Ex3 (Ex4 MText)]
  }
  deriving stock Generic
  deriving anyclass IsoValue

-- Check that the declarations generated by `deriveManyRPC` actually compile.
deriveManyRPC "ExampleMany" []

unit_Can_derive_many_instances_at_once :: Assertion
unit_Can_derive_many_instances_at_once = do
  shouldCompileIgnoringInstance ''Generic
    $(deriveManyRPC "ExampleMany" ["Ex3"] >>= TH.lift)
    [d|
      data ExampleManyRPC = ExampleManyRPC
        {_emField1RPC :: AsRPC Integer
        , _emField2RPC :: AsRPC Ex1
        , _emField3RPC :: AsRPC Ex2
        , _emField4RPC :: AsRPC [BigMap Ex3 (Ex4 MText)]
        }
      type instance AsRPC ExampleMany = ExampleManyRPC
      deriving anyclass instance IsoValue ExampleManyRPC

      -- An instance is generated for Ex1
      data Ex1RPC = Ex1RPC (AsRPC Integer) (AsRPC Ex1Inner)
      type instance AsRPC Ex1 = Ex1RPC
      deriving anyclass instance IsoValue Ex1RPC

      -- An instance is generated for Ex1's fields' types
      data Ex1InnerRPC = Ex1InnerRPC (AsRPC Integer)
      type instance AsRPC Ex1Inner = Ex1InnerRPC
      deriving anyclass instance IsoValue Ex1InnerRPC

      -- No instance is generated for Ex2, because one already exists

      -- No instance is generated for Ex3, because we explicitly said we don't want one

      -- An instance is generated for BigMap's concrete type arguments
      data Ex4RPC a = Ex4RPC (AsRPC a)
      type instance AsRPC (Ex4 a) = Ex4RPC a
      deriving anyclass instance IsoValue (AsRPC a) => IsoValue (Ex4RPC a)
    |]

----------------------------------------------------------------------------
-- AsRPC type family
----------------------------------------------------------------------------

checkLaws :: ToT (AsRPC t) :~: AsRPC (ToT t) -> ()
checkLaws Refl = ()

----------------------------------------------------------------------------
-- Examples data types:
--
-- Simple data type
----------------------------------------------------------------------------

data Simple = Simple Integer Integer [Integer]
  deriving stock Generic
  deriving anyclass IsoValue
deriveRPC "Simple"

data ExpectedSimpleRPC = ExpectedSimpleRPC Integer Integer [Integer]
  deriving stock Generic
  deriving anyclass IsoValue

_checkSimple :: ToT SimpleRPC :~: ToT ExpectedSimpleRPC
_checkSimple = Refl

_checkSimpleLaws :: ()
_checkSimpleLaws = checkLaws @Simple Refl

----------------------------------------------------------------------------
-- Simple record data type
----------------------------------------------------------------------------

data SimpleRecord = SimpleRecord
  { _simpleRecordField1 :: Integer
  , _simpleRecordField2 :: Integer
  , _simpleRecordField3 :: [Integer]
  }
  deriving stock Generic
  deriving anyclass IsoValue
deriveRPC "SimpleRecord"

data ExpectedSimpleRecordRPC = ExpectedSimpleRecordRPC
  { eSimpleRecordField1 :: Integer
  , eSimpleRecordField2 :: Integer
  , eSimpleRecordField3 :: [Integer]
  }
  deriving stock Generic
  deriving anyclass IsoValue

_checkSimpleRecord :: ToT SimpleRecordRPC :~: ToT ExpectedSimpleRecordRPC
_checkSimpleRecord = Refl

_checkSimpleRecordLaws :: ()
_checkSimpleRecordLaws = checkLaws @SimpleRecord Refl

----------------------------------------------------------------------------
-- Data type with bigmap fields
----------------------------------------------------------------------------

data WithBigMap = WithBigMap
  { _wbmField1 :: Integer
  , _wbmField2 :: BigMap Integer Integer
  , _wbmField3 :: [BigMap Integer Integer]
  }
  deriving stock Generic
  deriving anyclass IsoValue
deriveRPC "WithBigMap"

data ExpectedWithBigMapRPC = ExpectedWithBigMapRPC
  { expectedWbmField1 :: Integer
  , expectedWbmField2 :: BigMapId Integer Integer
  , expectedWbmField3 :: [BigMapId Integer Integer]
  }
  deriving stock Generic
  deriving anyclass IsoValue

_checkWithBigMap :: ToT WithBigMapRPC :~: ToT ExpectedWithBigMapRPC
_checkWithBigMap = Refl

_checkWithBigMapLaws :: ()
_checkWithBigMapLaws = checkLaws @WithBigMap Refl

----------------------------------------------------------------------------
-- Data type with custom generic strategy
----------------------------------------------------------------------------

data WithGenericStrategy
  = WithGenericStrategy_1 Integer Integer Integer
  | WithGenericStrategy_2 Integer Integer Integer
  | WithGenericStrategy_3 Integer Integer Integer
  | WithGenericStrategy_4 Integer Integer Integer

deriving anyclass instance IsoValue WithGenericStrategy
customGeneric "WithGenericStrategy" leftBalanced
deriveRPCWithStrategy "WithGenericStrategy" leftBalanced

_checkWithGenericStrategy :: ToT WithGenericStrategyRPC :~: ToT WithGenericStrategy
_checkWithGenericStrategy = Refl

_checkWithGenericStrategyLaws :: ()
_checkWithGenericStrategyLaws = checkLaws @WithGenericStrategy Refl

----------------------------------------------------------------------------
-- Data type with reordered fields
----------------------------------------------------------------------------

data WithReordered = WithRedordered
  { _wrField1 :: Integer
  , _wrField3 :: MText
  , _wrField2 :: [Integer]
  }

deriving anyclass instance IsoValue WithReordered
customGeneric "WithReordered" ligoLayout
deriveRPCWithStrategy "WithReordered" ligoLayout

_checkWithReordered :: ToT WithReorderedRPC :~: ToT WithReordered
_checkWithReordered = Refl

_checkWithReorderedLaws :: ()
_checkWithReorderedLaws = checkLaws @WithReordered Refl

----------------------------------------------------------------------------
-- Data type with type variables
----------------------------------------------------------------------------

data WithTypeVariables a = WithTypeVariables
  { _wtvField1 :: a
  }
  deriving stock Generic
  deriving anyclass IsoValue
deriveRPC "WithTypeVariables"

data ExpectedWithTypeVariablesRPC = ExpectedWithTypeVariablesRPC
  { expectedWtvField1 :: BigMapId Integer MText
  }
  deriving stock Generic
  deriving anyclass IsoValue

_checkWithTypeVariables :: ToT (WithTypeVariablesRPC (BigMap Integer MText)) :~: ToT ExpectedWithTypeVariablesRPC
_checkWithTypeVariables = Refl

_checkWithTypeVariablesLaws :: ()
_checkWithTypeVariablesLaws = checkLaws @(WithTypeVariables (BigMap Integer MText)) Refl

----------------------------------------------------------------------------
-- Data type with nested data types and type variables
----------------------------------------------------------------------------

data WithNested a = WithNested
  { _wnField1 :: WithNested2 a
  , _wnField2 :: [WithNested2 a]
  , _wnField3 :: WithNested2 [a]
  }
  deriving stock Generic
deriving anyclass instance IsoValue a => IsoValue (WithNested a)

data WithNested2 a = WithNested2
  { _wn2Field1 :: a
  , _wn2Field2 :: [a]
  }
  deriving stock Generic
  deriving anyclass IsoValue

deriveManyRPC "WithNested" []

data ExpectedWithNestedRPC = ExpectedWithNestedRPC
  { expectedWnField1 :: ExpectedWithNested2RPC
  , expectedWnField2 :: [ExpectedWithNested2RPC]
  , expectedWnField3 :: ExpectedWithNested2RPC'
  }
  deriving stock Generic
  deriving anyclass IsoValue

data ExpectedWithNested2RPC = ExpectedWithNested2RPC
  { expectedWn2Field1 :: BigMapId Integer MText
  , expectedWn2Field2 :: [BigMapId Integer MText]
  }
  deriving stock Generic
  deriving anyclass IsoValue

data ExpectedWithNested2RPC' = ExpectedWithNested2RPC'
  { expectedWn2Field1' :: [BigMapId Integer MText]
  , expectedWn2Field2' :: [[BigMapId Integer MText]]
  }
  deriving stock Generic
  deriving anyclass IsoValue

_checkWithNested2 :: ToT (WithNested2RPC (BigMap Integer MText)) :~: ToT ExpectedWithNested2RPC
_checkWithNested2 = Refl

_checkWithNested :: ToT (WithNestedRPC (BigMap Integer MText)) :~: ToT ExpectedWithNestedRPC
_checkWithNested = Refl

_checkWithNestedLaws :: ()
_checkWithNestedLaws = checkLaws @(WithNested (BigMap Integer MText)) Refl

_checkWithNested2Laws :: ()
_checkWithNested2Laws = checkLaws @(WithNested2 (BigMap Integer MText)) Refl

----------------------------------------------------------------------------
-- Data type with phantom type variables
----------------------------------------------------------------------------

data WithPhantom a b c = WithPhantom
  { _wpField1 :: Integer
  , _wpField2 :: b
  }
  deriving stock Generic
  deriving anyclass IsoValue
deriveRPC "WithPhantom"

data ExpectedWithPhantomRPC = ExpectedWithPhantomRPC
  { expectedWpField1 :: Integer
  , expectedWpField2 :: MText
  }
  deriving stock Generic
  deriving anyclass IsoValue

_checkWithPhantom :: ToT (WithPhantomRPC Integer MText (BigMap Integer Integer)) :~: ToT ExpectedWithPhantomRPC
_checkWithPhantom = Refl

_checkWithPhantomLaws :: ()
_checkWithPhantomLaws = checkLaws @(WithPhantom Integer MText (BigMap Integer Integer)) Refl

----------------------------------------------------------------------------
-- Data type with higher-kinded type variables
----------------------------------------------------------------------------

data WithHigherKind f = WithHigherKind
  { _whkField1 :: WithHigherKindNested f
  }
  deriving stock Generic
deriving anyclass instance (IsoValue (f Integer MText)) => IsoValue (WithHigherKind f)

data WithHigherKindNested f = WithHigherKindNested
  { _whknField1 :: f Integer MText
  }
  deriving stock Generic
deriving anyclass instance (IsoValue (f Integer MText)) => IsoValue (WithHigherKindNested f)

deriveManyRPC "WithHigherKind" []

unit_Supports_higher_kinded_types :: Assertion
unit_Supports_higher_kinded_types = do
  shouldCompileIgnoringInstance ''Generic
    $(deriveManyRPC "WithHigherKind" [] >>= TH.lift)
    [d|
      data WithHigherKindRPC (f :: * -> * -> *) = WithHigherKindRPC
        { _whkField1RPC :: AsRPC (WithHigherKindNested f)
        }
      type instance AsRPC (WithHigherKind (f :: * -> * -> *))
        = WithHigherKindRPC (f :: * -> * -> *)
      deriving anyclass instance IsoValue (AsRPC (WithHigherKindNested f))
        => IsoValue (WithHigherKindRPC (f :: * -> * -> *))

      data WithHigherKindNestedRPC (f :: * -> * -> *) = WithHigherKindNestedRPC
        { _whknField1RPC :: AsRPC (f Integer MText)
        }
      type instance AsRPC (WithHigherKindNested (f :: * -> * -> *))
        = WithHigherKindNestedRPC (f :: * -> * -> *)
      deriving anyclass instance IsoValue (AsRPC (f Integer MText))
        => IsoValue (WithHigherKindNestedRPC (f :: * -> * -> *))
    |]

data ExpectedWithHigherKindRPC = ExpectedWithHigherKindRPC
  { expectedWhkField1 :: ExpectedWithHigherKindNestedRPC
  }
  deriving stock Generic
  deriving anyclass IsoValue

data ExpectedWithHigherKindNestedRPC = ExpectedWithHigherKindNestedRPC
  { expectedWhknField1 :: Map Integer MText
  }
  deriving stock Generic
  deriving anyclass IsoValue

_checkWithHigherKindNested :: ToT (WithHigherKindNestedRPC Map) :~: ToT ExpectedWithHigherKindNestedRPC
_checkWithHigherKindNested = Refl

_checkWithHigherKind :: ToT (WithHigherKindRPC Map) :~: ToT ExpectedWithHigherKindRPC
_checkWithHigherKind = Refl

_checkWithHigherKindLaws :: ()
_checkWithHigherKindLaws = checkLaws @(WithHigherKind Map) Refl

_checkWithHigherKindNestedLaws :: ()
_checkWithHigherKindNestedLaws = checkLaws @(WithHigherKindNested Map) Refl

----------------------------------------------------------------------------
-- Newtypes allowed with deriveRPC and in deriveManyRPC
----------------------------------------------------------------------------

data Data1 b = Data1 b
  deriving stock (Generic, Eq, Ord)
  deriving anyclass IsoValue

deriveRPC "Data1"

newtype Nt1 a b = Nt1 [Data1 a]
  deriving stock (Generic, Eq, Ord)
deriving anyclass instance IsoValue a => IsoValue (Nt1 a b)

deriveRPC "Nt1"

unit_Can_derive_instances_with_newtype :: Assertion
unit_Can_derive_instances_with_newtype = do
  shouldCompileIgnoringInstance ''Generic
    $(deriveRPC "Nt1" >>= TH.lift)
    [d|
      newtype Nt1RPC a (b :: k) = Nt1RPC (AsRPC ([Data1 a]))
      type instance AsRPC (Nt1 a (b :: k)) = Nt1RPC a (b :: k)
      deriving anyclass instance IsoValue (AsRPC ([Data1 a])) => IsoValue (Nt1RPC a (b :: k))
    |]

newtype Nt2 = Nt2 { _nt2field :: Integer }
  deriving stock Generic
  deriving anyclass IsoValue

newtype Nt3 a = Nt3 a
  deriving stock Generic
  deriving anyclass IsoValue

newtype Nt4 a b = Nt4 (BigMap Integer MText)
  deriving stock Generic
  deriving anyclass IsoValue

newtype Nt5 a = Nt5 a
  deriving stock Generic
  deriving anyclass IsoValue

newtype Nt6 a = Nt6 (Nt5 a)
  deriving stock Generic
deriving anyclass instance IsoValue a => IsoValue (Nt6 a)

data Data2 a = Data2 (Nt6 a)
  deriving stock Generic
deriving anyclass instance IsoValue a => IsoValue (Data2 a)

data ExampleWithNewtypes = ExampleWithNewtypes
  { _ewnField1 :: Nt3 Nt2
  , _ewnField2 :: Nt4 MText Integer
  , _ewnField3 :: Data2 Integer
  }
  deriving stock Generic
  deriving anyclass IsoValue

deriveManyRPC "ExampleWithNewtypes" []

unit_Can_derive_many_instances_with_newtypes :: Assertion
unit_Can_derive_many_instances_with_newtypes = do
  shouldCompileIgnoringInstance ''Generic
    $(deriveManyRPC "ExampleWithNewtypes" [] >>= TH.lift)
    [d|
      data ExampleWithNewtypesRPC = ExampleWithNewtypesRPC
        {_ewnField1RPC :: (AsRPC (Nt3 Nt2))
        , _ewnField2RPC :: (AsRPC (Nt4 MText Integer))
        , _ewnField3RPC :: (AsRPC (Data2 Integer))
        }

      type instance AsRPC ExampleWithNewtypes = ExampleWithNewtypesRPC
      deriving anyclass instance IsoValue ExampleWithNewtypesRPC

      newtype Nt3RPC a = Nt3RPC (AsRPC a)
      type instance AsRPC (Nt3 a) = Nt3RPC a
      deriving anyclass instance IsoValue (AsRPC a) => IsoValue (Nt3RPC a)

      newtype Nt2RPC = Nt2RPC {_nt2fieldRPC :: (AsRPC Integer)}
      type instance AsRPC Nt2 = Nt2RPC
      deriving anyclass instance IsoValue Nt2RPC

      newtype Nt4RPC (a :: k) (b :: k) = Nt4RPC (AsRPC (BigMap Integer MText))
      type instance AsRPC (Nt4 (a :: k) (b :: k)) = Nt4RPC (a :: k) (b :: k)
      deriving anyclass instance IsoValue (Nt4RPC (a :: k) (b :: k))

      data Data2RPC a = Data2RPC (AsRPC (Nt6 a))
      type instance AsRPC (Data2 a) = Data2RPC a
      deriving anyclass instance IsoValue (AsRPC (Nt6 a)) => IsoValue (Data2RPC a)

      newtype Nt6RPC a = Nt6RPC (AsRPC (Nt5 a))
      type instance AsRPC (Nt6 a) = Nt6RPC a
      deriving anyclass instance IsoValue (AsRPC (Nt5 a)) => IsoValue (Nt6RPC a)

      newtype Nt5RPC a = Nt5RPC (AsRPC a)
      type instance AsRPC (Nt5 a) = Nt5RPC a
      deriving anyclass instance IsoValue (AsRPC a) => IsoValue (Nt5RPC a)
    |]

----------------------------------------------------------------------------
-- Type aliases allowed with deriveManyRPC
----------------------------------------------------------------------------

type Ty1 = Integer

type Ty2 k v = BigMap k v

type Ty3 phantom = Ty1

data Dt1 = Dt1 Integer
  deriving stock (Generic, Eq, Ord)
  deriving anyclass IsoValue

data Dt2 a = Dt2 a
  deriving stock Generic
  deriving anyclass IsoValue

type Ty4 = Dt1

type Ty5 a = Dt2 a

data Dt3 k v = Dt3 k v
  deriving stock (Generic, Eq, Ord)
  deriving anyclass IsoValue

type Ty6 v = Dt3 Integer v

data Dt4 v = Dt4 (Ty6 v)
  deriving stock (Generic, Eq, Ord)
deriving anyclass instance IsoValue v => IsoValue (Dt4 v)

data Dt5 a = Dt5 a
  deriving stock Generic
  deriving anyclass IsoValue

type Ty7 (f :: Type -> Type) = (f Integer)

data Dt6 = Dt6 Integer
  deriving stock (Generic, Eq, Ord)
  deriving anyclass IsoValue

data Dt7 a b = Dt7 a b
  deriving stock Generic
  deriving anyclass IsoValue

data Dt8 = Dt8 [BigMap Integer MText]
  deriving stock Generic
  deriving anyclass IsoValue

type Ty8 (f :: Type -> Type -> Type) a = f a Dt6
type Ty9 (f :: Type -> Type -> Type) a = Ty8 f a
type Ty10 (f :: Type -> Type -> Type) a = Ty9 f a

data ExampleTypeAliasMany = ExampleTypeAliasMany
  { _etamField1 :: Ty1
  , _etamField2 :: Ty2 Integer MText
  , _etamField3 :: Ty3 Integer
  , _etamField4 :: Ty4
  , _etamField5 :: Ty5 Integer
  , _etamField6 :: Ty6 MText
  , _etamField7 :: Ty7 Dt5
  , _etamField8 :: Ty10 Dt7 Dt8
  , _etamField9 :: Dt4 Integer
  }
  deriving stock Generic
  deriving anyclass IsoValue

-- Check that the declarations generated by `deriveManyRPC` actually compile.
deriveManyRPC "ExampleTypeAliasMany" []

unit_Can_derive_many_instances_with_type_aliases :: Assertion
unit_Can_derive_many_instances_with_type_aliases = do
  shouldCompileIgnoringInstance ''Generic
    $(deriveManyRPC "ExampleTypeAliasMany" [] >>= TH.lift)
    [d|
      data ExampleTypeAliasManyRPC = ExampleTypeAliasManyRPC
        { _etamField1RPC :: AsRPC Ty1
        , _etamField2RPC :: AsRPC (Ty2 Integer MText)
        , _etamField3RPC :: AsRPC (Ty3 Integer)
        , _etamField4RPC :: AsRPC Ty4
        , _etamField5RPC :: AsRPC (Ty5 Integer)
        , _etamField6RPC :: AsRPC (Ty6 MText)
        , _etamField7RPC :: AsRPC (Ty7 Dt5)
        , _etamField8RPC :: AsRPC (Ty10 Dt7 Dt8)
        , _etamField9RPC :: AsRPC (Dt4 Integer)
        }
      type instance AsRPC ExampleTypeAliasMany = ExampleTypeAliasManyRPC
      deriving anyclass instance IsoValue ExampleTypeAliasManyRPC

      -- An instance is generated for Dt1
      data Dt1RPC = Dt1RPC (AsRPC Integer)
      type instance AsRPC Dt1 = Dt1RPC
      deriving anyclass instance IsoValue Dt1RPC

      -- An instance is generated for Dt2
      data Dt2RPC a = Dt2RPC (AsRPC a)
      type instance AsRPC (Dt2 a) = Dt2RPC a
      deriving anyclass instance IsoValue (AsRPC a) => IsoValue (Dt2RPC a)

      -- An instance is generated for Dt3
      data Dt3RPC k v = Dt3RPC (AsRPC k) (AsRPC v)
      type instance AsRPC (Dt3 k v) = Dt3RPC k v
      deriving anyclass instance (IsoValue (AsRPC k), IsoValue (AsRPC v)) => IsoValue (Dt3RPC k v)

      -- An instance is generated for Dt5
      data Dt5RPC a = Dt5RPC (AsRPC a)
      type instance AsRPC (Dt5 a) = Dt5RPC a
      deriving anyclass instance IsoValue (AsRPC a) => IsoValue (Dt5RPC a)

      -- An instance is generated for Dt6
      data Dt6RPC = Dt6RPC (AsRPC Integer)
      type instance AsRPC Dt6 = Dt6RPC
      deriving anyclass instance IsoValue Dt6RPC

      -- An instance is generated for Dt7
      data Dt7RPC a b = Dt7RPC (AsRPC a) (AsRPC b)
      type instance AsRPC (Dt7 a b) = Dt7RPC a b
      deriving anyclass instance (IsoValue (AsRPC a), IsoValue (AsRPC b)) => IsoValue (Dt7RPC a b)

      -- An instance is generated for Dt8
      data Dt8RPC = Dt8RPC (AsRPC ([BigMap Integer MText]))
      type instance AsRPC Dt8 = Dt8RPC
      deriving anyclass instance IsoValue Dt8RPC

      -- An instance is generated for Dt4
      data Dt4RPC v = Dt4RPC (AsRPC (Ty6 v))
      type instance AsRPC (Dt4 v) = Dt4RPC v
      deriving anyclass instance IsoValue (AsRPC (Ty6 v)) => IsoValue (Dt4RPC v)
    |]