content: {-# LANGUAGE CPP #-}
  
  module Vulkan.Internal.Utils
    ( enumReadPrec
    , enumShowsPrec
    , traceAroundEvent
    ) where
  
  import           Data.Foldable
  import           Debug.Trace
  import           GHC.Read                       ( expectP )
  import           Text.ParserCombinators.ReadP   ( skipSpaces
                                                  , string
                                                  )
  import           Text.Read
  
  -- | The common bits of enumeration and bitmask read instances
  enumReadPrec
    :: Read i
    => String
    -- ^ The common constructor prefix
    -> [(a, String)]
    -- ^ The table of values to constructor suffixes
    -> String
    -- ^ The newtype constructor name
    -> (i -> a)
    -- ^ The newtype constructor
    -> ReadPrec a
  enumReadPrec prefix table conName con = parens
    (   lift
        (do
          skipSpaces
          _ <- string prefix
          asum ((\(e, s) -> e <$ string s) <$> table)
        )
    +++ prec
          10
          (do
            expectP (Ident conName)
            v <- step readPrec
            pure (con v)
          )
    )
  
  -- | The common bits of enumeration and bitmask show instances
  enumShowsPrec
    :: Eq a
    => String
    -- ^ The common constructor prefix
    -> [(a, String)]
    -- ^ A table of values to constructor suffixes
    -> String
    -- ^ The newtype constructor name
    -> (a -> i)
    -- ^ Unpack the newtype
    -> (i -> ShowS)
    -- ^ Show the underlying value
    -> Int
    -> a
    -> ShowS
  enumShowsPrec prefix table conName getInternal showsInternal p e =
    case lookup e table of
      Just s -> showString prefix . showString s
      Nothing ->
        let x = getInternal e
        in  showParen (p >= 11)
                      (showString conName . showString " " . showsInternal x)
  
  -- | Wrap an IO action with a pair of 'traceEventIO' using the specified
  -- message with "begin" or "end" appended.
  traceAroundEvent :: String -> IO a -> IO a
  #if defined(TRACE_CALLS)
  traceAroundEvent msg a =
    traceEventIO (msg <> " begin") *> a <* traceEventIO (msg <> " end")
  #else
  traceAroundEvent _ a = a
  #endif
  