{-# LANGUAGE BlockArguments #-}

module Internal.IO
  ( putText,
    putTextLn,
  )
where

import Control.Concurrent.MVar
import System.IO.Unsafe (unsafePerformIO)
import Text
import qualified Prelude

{-# NOINLINE stdoutLock #-}
stdoutLock :: MVar ()
stdoutLock :: MVar ()
stdoutLock = IO (MVar ()) -> MVar ()
forall a. IO a -> a
unsafePerformIO (() -> IO (MVar ())
forall a. a -> IO (MVar a)
newMVar ())

-- Output functions

-- | Write text to stdout.
--
-- This function is similar to `Prelude.putStr` but receives a `Text` instead of a `Prelude.String`.
-- Also this function is thread-safe, using a lock to prevent interleaved output.
putText :: Text -> Prelude.IO ()
putText :: Text -> IO ()
putText Text
text = do
  MVar () -> (() -> IO ()) -> IO ()
forall a b. MVar a -> (a -> IO b) -> IO b
withMVar MVar ()
stdoutLock \()
_ ->
    String -> IO ()
Prelude.putStr (Text -> String
Text.toList Text
text)

-- | Write text to stdout followed by a newline.
--
-- This function is similar to `Prelude.putStrLn` but receives a `Text` instead of a `Prelude.String`.
-- Also this function is thread-safe, using a lock to prevent interleaved output.
putTextLn :: Text -> Prelude.IO ()
putTextLn :: Text -> IO ()
putTextLn Text
text = do
  MVar () -> (() -> IO ()) -> IO ()
forall a b. MVar a -> (a -> IO b) -> IO b
withMVar MVar ()
stdoutLock \()
_ ->
    String -> IO ()
Prelude.putStrLn (Text -> String
Text.toList Text
text)