|
| 1 | +{-# LANGUAGE FlexibleInstances #-} |
| 2 | +{-# LANGUAGE GADTs #-} |
| 3 | +{-# LANGUAGE GeneralizedNewtypeDeriving #-} |
| 4 | +{-# LANGUAGE MultiParamTypeClasses #-} |
| 5 | +{-# LANGUAGE RankNTypes #-} |
| 6 | +{-# LANGUAGE TypeApplications #-} |
| 7 | +{-# LANGUAGE TypeOperators #-} |
| 8 | +{-# LANGUAGE UndecidableInstances #-} |
| 9 | + |
| 10 | +module Control.Carrier.Logger.IO ( |
| 11 | + HandleSelector, |
| 12 | + singleHandle, |
| 13 | + runLoggerIO, |
| 14 | +) where |
| 15 | + |
| 16 | +import Control.Algebra (Algebra (..), (:+:) (..)) |
| 17 | +import Control.Carrier.Reader (ReaderC, runReader) |
| 18 | +import Control.Effect.Logger (Logger (..)) |
| 19 | +import Control.Effect.Reader (ask) |
| 20 | +import Control.Monad.IO.Class (MonadIO (..)) |
| 21 | +import Control.Monad.Logger ( |
| 22 | + Loc, |
| 23 | + LogLevel, |
| 24 | + LogSource, |
| 25 | + LogStr, |
| 26 | + ToLogStr (..), |
| 27 | + defaultLogStr, |
| 28 | + fromLogStr, |
| 29 | + ) |
| 30 | +import qualified Data.ByteString.Char8 as B (hPutStr) |
| 31 | +import System.IO (Handle) |
| 32 | + |
| 33 | +-- | Algebra for a simple IO logger. The inner function allows for selecting a |
| 34 | +-- 'Handle' according to something like 'LogLevel'. |
| 35 | +newtype LoggerIOC f m a = LoggerIOC |
| 36 | + { runLoggerIOC :: ReaderC f m a |
| 37 | + } |
| 38 | + deriving (Applicative, Functor, Monad, MonadIO) |
| 39 | + |
| 40 | +type HandleSelector = Loc -> LogSource -> LogLevel -> LogStr -> Handle |
| 41 | + |
| 42 | +singleHandle :: Handle -> HandleSelector |
| 43 | +singleHandle h _ _ _ _ = h |
| 44 | + |
| 45 | +instance |
| 46 | + forall sig m |
| 47 | + . ( Algebra sig m |
| 48 | + , MonadIO m |
| 49 | + ) |
| 50 | + => Algebra (Logger :+: sig) (LoggerIOC HandleSelector m) |
| 51 | + where |
| 52 | + alg hdl sig ctx = case sig of |
| 53 | + L (LoggerLog loc src lvl msg) -> LoggerIOC $ do |
| 54 | + f <- ask |
| 55 | + ctx |
| 56 | + <$ liftIO |
| 57 | + ( B.hPutStr |
| 58 | + (f loc src lvl (toLogStr msg)) |
| 59 | + (fromLogStr (defaultLogStr loc src lvl (toLogStr msg))) |
| 60 | + ) |
| 61 | + R other -> LoggerIOC (alg (runLoggerIOC . hdl) (R other) ctx) |
| 62 | + |
| 63 | +-- | Run a logger by writing to a 'Handle'. |
| 64 | +runLoggerIO |
| 65 | + :: HandleSelector |
| 66 | + -> LoggerIOC HandleSelector m a |
| 67 | + -> m a |
| 68 | +runLoggerIO f = runReader f . runLoggerIOC |
0 commit comments