{-# LANGUAGE CPP              #-}
{-# LANGUAGE TypeApplications #-}
module Ouroboros.Consensus.Util.Assert (
    assertEqWithMsg
  , assertWithMsg
  ) where

import           GHC.Stack (HasCallStack)

import           Ouroboros.Consensus.Util.RedundantConstraints

assertWithMsg :: HasCallStack => Either String () -> a -> a
#if ENABLE_ASSERTIONS
assertWithMsg :: Either String () -> a -> a
assertWithMsg (Left String
msg) a
_ = String -> a
forall a. HasCallStack => String -> a
error String
msg
#endif
assertWithMsg Either String ()
_          a
a = a
a
  where
    ()
_ = Proxy HasCallStack -> ()
forall (c :: Constraint) (proxy :: Constraint -> *).
c =>
proxy c -> ()
keepRedundantConstraint (Proxy HasCallStack
forall k (t :: k). Proxy t
Proxy @HasCallStack)

assertEqWithMsg :: (Eq b, Show b, HasCallStack) => (b, b) -> a -> a
assertEqWithMsg :: (b, b) -> a -> a
assertEqWithMsg (b
x, b
y) = Either String () -> a -> a
forall a. HasCallStack => Either String () -> a -> a
assertWithMsg Either String ()
msg
  where
    msg :: Either String ()
    msg :: Either String ()
msg | b
x b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
y    = () -> Either String ()
forall a b. b -> Either a b
Right ()
        | Bool
otherwise = String -> Either String ()
forall a b. a -> Either a b
Left (String -> Either String ()) -> String -> Either String ()
forall a b. (a -> b) -> a -> b
$ b -> String
forall a. Show a => a -> String
show b
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" /= " String -> String -> String
forall a. [a] -> [a] -> [a]
++ b -> String
forall a. Show a => a -> String
show b
y