{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Util.Serialisation.SomeResult (SomeResult (..)) where

import           Data.Typeable
import           Ouroboros.Consensus.Ledger.Query (BlockQuery)

-- | To easily generate all the possible @result@s of the 'Query' GADT, we
-- introduce an existential that also bundles the corresponding 'Query' as
-- evidence. We also capture 'Eq', 'Show', and 'Typeable' constraints, as we
-- need them in the tests.
data SomeResult blk where
  SomeResult :: (Eq result, Show result, Typeable result)
             => BlockQuery blk result -> result -> SomeResult blk

instance Show (SomeResult blk) where
  show :: SomeResult blk -> String
show (SomeResult BlockQuery blk result
_ result
result) = result -> String
forall a. Show a => a -> String
show result
result

instance Eq (SomeResult blk) where
  SomeResult BlockQuery blk result
_ (result
res1 :: result1) == :: SomeResult blk -> SomeResult blk -> Bool
== SomeResult BlockQuery blk result
_ (result
res2 :: result2) =
    case forall {k} (a :: k) (b :: k).
(Typeable a, Typeable b) =>
Maybe (a :~: b)
forall a b. (Typeable a, Typeable b) => Maybe (a :~: b)
eqT @result1 @result2 of
      Maybe (result :~: result)
Nothing   -> Bool
False
      Just result :~: result
Refl -> result
res1 result -> result -> Bool
forall a. Eq a => a -> a -> Bool
== result
result
res2