    {-|
    Module      : HsLua.Core.Warn
    Copyright   : © 2023-2024 Albert Krewinkel
    License     : MIT
    Maintainer  : Albert Krewinkel <tarleb@hslua.org>

    Simpler interface to the Lua warnings system.

    This module simplifies the process of setting a custom warn function.
    -}
    module HsLua.Core.Warn
      ( setwarnf'
      ) where

    import Data.ByteString (ByteString)
    import HsLua.Core.Closures (pushHaskellFunction)
    import HsLua.Core.Error (LuaError)
    import HsLua.Core.Primary (tostring)
    import HsLua.Core.Types (LuaE, NumResults (..), liftLua, nthBottom)
    import Lua.Warn (hsluaL_setwarnf)

    -- | Sets a warning function. This is a simplified version of
    -- 'lua_setwarnf'. The given function is called with the concatenated
    -- warning components as the single argument.
    --
    -- Control messages are handled internally and are /not/ passed on the
    -- warning hook. As with the default warning function, the control
    -- messages @\@on@ and @\@off@ can switch error reporting to stderr on
    -- and off. The given Haskell function will be called in either case,
    -- even when the error is not written to stderr.
    --
    -- Wraps 'hsluaL_setwarnf'.
    setwarnf' :: LuaError e
              => (ByteString -> LuaE e ())
              -> LuaE e ()
    setwarnf' :: forall e. LuaError e => (ByteString -> LuaE e ()) -> LuaE e ()
    setwarnf' ByteString -> LuaE e ()
    fn = do
      HaskellFunction e -> LuaE e ()
    forall e. LuaError e => HaskellFunction e -> LuaE e ()
    pushHaskellFunction (HaskellFunction e -> LuaE e ()) -> HaskellFunction e -> LuaE e ()
    forall a b. (a -> b) -> a -> b
    $ do
        mbmsg <- StackIndex -> LuaE e (Maybe ByteString)
    forall e. StackIndex -> LuaE e (Maybe ByteString)
    tostring (CInt -> StackIndex
    nthBottom CInt
    1)
        case mbmsg of
          Maybe ByteString
    Nothing  -> NumResults -> HaskellFunction e
    forall a. a -> LuaE e a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (CInt -> NumResults
    NumResults CInt
    0)  -- couldn't get warning msg; do nothing
          Just ByteString
    msg -> CInt -> NumResults
    NumResults CInt
    0 NumResults -> LuaE e () -> HaskellFunction e
    forall a b. a -> LuaE e b -> LuaE e a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ ByteString -> LuaE e ()
    fn ByteString
    msg
      (State -> IO ()) -> LuaE e ()
    forall a e. (State -> IO a) -> LuaE e a
    liftLua State -> IO ()
    hsluaL_setwarnf