{-|
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
    Maybe ByteString
mbmsg <- StackIndex -> LuaE e (Maybe ByteString)
forall e. StackIndex -> LuaE e (Maybe ByteString)
tostring (CInt -> StackIndex
nthBottom CInt
1)
    case Maybe ByteString
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