-- |Description: Internal
module Polysemy.Log.Log where

import Polysemy.Internal (InterpretersFor)
import Polysemy.Time (GhcTime, interpretTimeGhc)

import Polysemy.Log.Data.DataLog (DataLog, dataLog)
import Polysemy.Log.Data.Log (Log(Log))
import Polysemy.Log.Data.LogEntry (LogEntry, annotate)
import Polysemy.Log.Data.LogMessage (LogMessage)
import Polysemy.Log.Data.LogMetadata (LogMetadata(Annotated), annotated)

-- |Interpret 'Log' into the intermediate internal effect 'LogMetadata'.
interpretLogLogMetadata ::
  Members [LogMetadata LogMessage, GhcTime] r =>
  InterpreterFor Log r
interpretLogLogMetadata :: InterpreterFor Log r
interpretLogLogMetadata =
  (forall x (rInitial :: EffectRow). Log (Sem rInitial) x -> Sem r x)
-> Sem (Log : r) a -> Sem r a
forall (e :: Effect) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall x (rInitial :: EffectRow). e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Log msg -> LogMessage -> Sem r ()
forall a (r :: EffectRow).
(MemberWithError (LogMetadata a) r, HasCallStack) =>
a -> Sem r ()
annotated LogMessage
msg
{-# INLINE interpretLogLogMetadata #-}

-- |Interpret the intermediate internal effect 'LogMetadata' into 'DataLog'.
--
-- Since this adds a timestamp, it has a dependency on 'GhcTime'.
-- Use 'interpretLogMetadataDataLog'' for a variant that interprets 'GhcTime' in-place.
interpretLogMetadataDataLog ::
   a r .
  Members [DataLog (LogEntry a), GhcTime] r =>
  InterpreterFor (LogMetadata a) r
interpretLogMetadataDataLog :: InterpreterFor (LogMetadata a) r
interpretLogMetadataDataLog =
  (forall x (rInitial :: EffectRow).
 LogMetadata a (Sem rInitial) x -> Sem r x)
-> Sem (LogMetadata a : r) a -> Sem r a
forall (e :: Effect) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall x (rInitial :: EffectRow). e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Annotated msg -> LogEntry a -> Sem r ()
forall a (r :: EffectRow).
MemberWithError (DataLog a) r =>
a -> Sem r ()
dataLog (LogEntry a -> Sem r ()) -> Sem r (LogEntry a) -> Sem r ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> Sem r (LogEntry a)
forall (r :: EffectRow) a.
(HasCallStack, Member GhcTime r) =>
a -> Sem r (LogEntry a)
annotate a
msg
{-# INLINE interpretLogMetadataDataLog #-}

-- |Interpret the intermediate internal effect 'LogMetadata' into 'DataLog'.
interpretLogMetadataDataLog' ::
  Members [DataLog (LogEntry a), Embed IO] r =>
  InterpretersFor [LogMetadata a, GhcTime] r
interpretLogMetadataDataLog' :: InterpretersFor '[LogMetadata a, GhcTime] r
interpretLogMetadataDataLog' =
  Sem (GhcTime : r) a -> Sem r a
forall (r :: EffectRow).
Member (Embed IO) r =>
InterpreterFor GhcTime r
interpretTimeGhc (Sem (GhcTime : r) a -> Sem r a)
-> (Sem (LogMetadata a : GhcTime : r) a -> Sem (GhcTime : r) a)
-> Sem (LogMetadata a : GhcTime : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sem (LogMetadata a : GhcTime : r) a -> Sem (GhcTime : r) a
forall a (r :: EffectRow).
Members '[DataLog (LogEntry a), GhcTime] r =>
InterpreterFor (LogMetadata a) r
interpretLogMetadataDataLog
{-# INLINE interpretLogMetadataDataLog' #-}

-- |Interpret 'Log' into 'DataLog', adding metadata information and wrapping with 'LogEntry'.
--
-- Since this adds a timestamp, it has a dependency on 'GhcTime'.
-- Use 'interpretLogDataLog'' for a variant that interprets 'GhcTime' in-place.
interpretLogDataLog ::
  Members [DataLog (LogEntry LogMessage), GhcTime] r =>
  InterpreterFor Log r
interpretLogDataLog :: InterpreterFor Log r
interpretLogDataLog =
  forall (r :: EffectRow).
Members '[DataLog (LogEntry LogMessage), GhcTime] r =>
InterpreterFor (LogMetadata LogMessage) r
forall a (r :: EffectRow).
Members '[DataLog (LogEntry a), GhcTime] r =>
InterpreterFor (LogMetadata a) r
interpretLogMetadataDataLog @LogMessage (Sem (LogMetadata LogMessage : r) a -> Sem r a)
-> (Sem (Log : r) a -> Sem (LogMetadata LogMessage : r) a)
-> Sem (Log : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sem (Log : LogMetadata LogMessage : r) a
-> Sem (LogMetadata LogMessage : r) a
forall (r :: EffectRow).
Members '[LogMetadata LogMessage, GhcTime] r =>
InterpreterFor Log r
interpretLogLogMetadata (Sem (Log : LogMetadata LogMessage : r) a
 -> Sem (LogMetadata LogMessage : r) a)
-> (Sem (Log : r) a -> Sem (Log : LogMetadata LogMessage : r) a)
-> Sem (Log : r) a
-> Sem (LogMetadata LogMessage : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sem (Log : r) a -> Sem (Log : LogMetadata LogMessage : r) a
forall (e2 :: Effect) (e1 :: Effect) (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder
{-# INLINE interpretLogDataLog #-}

-- |Interpret 'Log' into 'DataLog', adding metadata information and wrapping with 'LogEntry'.
interpretLogDataLog' ::
  Member (Embed IO) r =>
  Member (DataLog (LogEntry LogMessage)) r =>
  InterpretersFor [Log, LogMetadata LogMessage, GhcTime] r
interpretLogDataLog' :: InterpretersFor '[Log, LogMetadata LogMessage, GhcTime] r
interpretLogDataLog' =
  Sem (LogMetadata LogMessage : GhcTime : r) a -> Sem r a
forall a (r :: EffectRow).
Members '[DataLog (LogEntry a), Embed IO] r =>
InterpretersFor '[LogMetadata a, GhcTime] r
interpretLogMetadataDataLog' (Sem (LogMetadata LogMessage : GhcTime : r) a -> Sem r a)
-> (Sem (Log : LogMetadata LogMessage : GhcTime : r) a
    -> Sem (LogMetadata LogMessage : GhcTime : r) a)
-> Sem (Log : LogMetadata LogMessage : GhcTime : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sem (Log : LogMetadata LogMessage : GhcTime : r) a
-> Sem (LogMetadata LogMessage : GhcTime : r) a
forall (r :: EffectRow).
Members '[LogMetadata LogMessage, GhcTime] r =>
InterpreterFor Log r
interpretLogLogMetadata
{-# INLINE interpretLogDataLog' #-}