module Effectful.Zoo.Log.Data.Logger
  ( Logger(..),
    mkLogger,
  ) where

import Effectful
import Effectful.Zoo.Core
import Effectful.Zoo.Log.Data.Severity
import HaskellWorks.Prelude

newtype Logger i = Logger
  { forall i. Logger i -> CallStack -> Severity -> i -> IO ()
run :: CallStack -> Severity -> i -> IO ()
  } deriving stock (forall x. Logger i -> Rep (Logger i) x)
-> (forall x. Rep (Logger i) x -> Logger i) -> Generic (Logger i)
forall x. Rep (Logger i) x -> Logger i
forall x. Logger i -> Rep (Logger i) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall i x. Rep (Logger i) x -> Logger i
forall i x. Logger i -> Rep (Logger i) x
$cfrom :: forall i x. Logger i -> Rep (Logger i) x
from :: forall x. Logger i -> Rep (Logger i) x
$cto :: forall i x. Rep (Logger i) x -> Logger i
to :: forall x. Rep (Logger i) x -> Logger i
Generic

instance Contravariant Logger where
  contramap :: forall a' a. (a' -> a) -> Logger a -> Logger a'
contramap a' -> a
f (Logger CallStack -> Severity -> a -> IO ()
g) = (CallStack -> Severity -> a' -> IO ()) -> Logger a'
forall i. (CallStack -> Severity -> i -> IO ()) -> Logger i
Logger \CallStack
cs Severity
severity -> CallStack -> Severity -> a -> IO ()
g CallStack
cs Severity
severity (a -> IO ()) -> (a' -> a) -> a' -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
f

mkLogger :: ()
  => r <: IOE
  => UnliftStrategy
  -> (CallStack -> Severity -> i -> Eff r ())
  -> Eff r (Logger i)
mkLogger :: forall (r :: [Effect]) i.
(r <: IOE) =>
UnliftStrategy
-> (CallStack -> Severity -> i -> Eff r ()) -> Eff r (Logger i)
mkLogger UnliftStrategy
strategy CallStack -> Severity -> i -> Eff r ()
run =
  UnliftStrategy
-> ((forall {r}. Eff r r -> IO r) -> IO (Logger i))
-> Eff r (Logger i)
forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
UnliftStrategy
-> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
withEffToIO UnliftStrategy
strategy (((forall {r}. Eff r r -> IO r) -> IO (Logger i))
 -> Eff r (Logger i))
-> ((forall {r}. Eff r r -> IO r) -> IO (Logger i))
-> Eff r (Logger i)
forall a b. (a -> b) -> a -> b
$ \forall {r}. Eff r r -> IO r
effToIO ->
    Logger i -> IO (Logger i)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Logger i -> IO (Logger i)) -> Logger i -> IO (Logger i)
forall a b. (a -> b) -> a -> b
$ (CallStack -> Severity -> i -> IO ()) -> Logger i
forall i. (CallStack -> Severity -> i -> IO ()) -> Logger i
Logger ((CallStack -> Severity -> i -> IO ()) -> Logger i)
-> (CallStack -> Severity -> i -> IO ()) -> Logger i
forall a b. (a -> b) -> a -> b
$ \CallStack
cs Severity
severity i
i -> Eff r () -> IO ()
forall {r}. Eff r r -> IO r
effToIO (Eff r () -> IO ()) -> Eff r () -> IO ()
forall a b. (a -> b) -> a -> b
$ CallStack -> Severity -> i -> Eff r ()
run CallStack
cs Severity
severity i
i