-- | A simple system so that the Cryptol driver can communicate
-- with users (or not).
module Cryptol.Utils.Logger
  ( Logger

  , stdoutLogger
  , stderrLogger
  , handleLogger
  , quietLogger
  , funLogger

  , logPutStr
  , logPutStrLn
  , logPrint
  ) where

import System.IO(Handle, hPutStr, stdout, stderr)
import Control.DeepSeq(NFData(..))

-- | A logger provides simple abstraction for sending messages.
newtype Logger = Logger (String -> IO ())

instance NFData Logger where
  rnf :: Logger -> ()
rnf (Logger String -> IO ()
x) = (String -> IO ()) -> ()
forall a. NFData a => a -> ()
rnf String -> IO ()
x

-- | Send the given string to the log.
logPutStr :: Logger -> String -> IO ()
logPutStr :: Logger -> String -> IO ()
logPutStr (Logger String -> IO ()
f) = String -> IO ()
f

-- | Send the given string with a newline at the end.
logPutStrLn :: Logger -> String -> IO ()
logPutStrLn :: Logger -> String -> IO ()
logPutStrLn Logger
l String
s = Logger -> String -> IO ()
logPutStr Logger
l (String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n")

-- | Send the given value using its 'Show' instance.
-- Adds a newline at the end.
logPrint :: Show a => Logger -> a -> IO ()
logPrint :: Logger -> a -> IO ()
logPrint Logger
l a
a = Logger -> String -> IO ()
logPutStrLn Logger
l (a -> String
forall a. Show a => a -> String
show a
a)

-- | A logger that ignores all messages.
quietLogger :: Logger
quietLogger :: Logger
quietLogger = (String -> IO ()) -> Logger
Logger (IO () -> String -> IO ()
forall a b. a -> b -> a
const (() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()))

-- | Log to the given handle.
handleLogger :: Handle -> Logger
handleLogger :: Handle -> Logger
handleLogger Handle
h = (String -> IO ()) -> Logger
Logger (Handle -> String -> IO ()
hPutStr Handle
h)

-- | Log to stdout.
stdoutLogger :: Logger
stdoutLogger :: Logger
stdoutLogger = Handle -> Logger
handleLogger Handle
stdout

-- | Log to stderr.
stderrLogger :: Logger
stderrLogger :: Logger
stderrLogger = Handle -> Logger
handleLogger Handle
stderr

-- | Just use this function for logging.
funLogger :: (String -> IO ()) -> Logger
funLogger :: (String -> IO ()) -> Logger
funLogger = (String -> IO ()) -> Logger
Logger