module Effectful.Zoo.DataLog.Static
  ( DataLog,
    runDataLog,
    runDataLogTextToHandle,
    runDataLogTextToStdout,
    runDataLogTextToStderr,
    withDataLog,
    log,
    local,
  ) where

import Data.Text.IO qualified as T
import Data.Kind
import Effectful
import Effectful.Zoo.Core
import Effectful.Dispatch.Static
import Effectful.Zoo.DataLog.Data.DataLogger
import HaskellWorks.Prelude
import System.IO qualified as IO

data DataLog (i :: Type) :: Effect

type instance DispatchOf (DataLog i) = Static NoSideEffects

newtype instance StaticRep (DataLog i) = DataLog (DataLogger i)

runDataLog :: forall i a r. ()
  => HasCallStack
  => (HasCallStack => i -> Eff r ())
  -> Eff (DataLog i : r) a
  -> Eff r a
runDataLog :: forall i a (r :: [Effect]).
HasCallStack =>
(HasCallStack => i -> Eff r ()) -> Eff (DataLog i : r) a -> Eff r a
runDataLog HasCallStack => i -> Eff r ()
run Eff (DataLog i : r) a
f = do
  DataLogger i
s <- (i -> Eff r ()) -> Eff r (DataLogger i)
forall i (r :: [Effect]). (i -> Eff r ()) -> Eff r (DataLogger i)
mkDataLogger i -> Eff r ()
HasCallStack => i -> Eff r ()
run
  StaticRep (DataLog i) -> Eff (DataLog i : r) a -> Eff r a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
 MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep (DataLogger i -> StaticRep (DataLog i)
forall i. DataLogger i -> StaticRep (DataLog i)
DataLog DataLogger i
s) Eff (DataLog i : r) a
f

runDataLogTextToHandle :: ()
  => HasCallStack
  => Handle
  -> Eff (DataLog Text : r) a
  -> Eff r a
runDataLogTextToHandle :: forall (r :: [Effect]) a.
HasCallStack =>
Handle -> Eff (DataLog Text : r) a -> Eff r a
runDataLogTextToHandle Handle
h =
  StaticRep (DataLog Text) -> Eff (DataLog Text : r) a -> Eff r a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
 MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep (StaticRep (DataLog Text) -> Eff (DataLog Text : r) a -> Eff r a)
-> StaticRep (DataLog Text) -> Eff (DataLog Text : r) a -> Eff r a
forall a b. (a -> b) -> a -> b
$ DataLogger Text -> StaticRep (DataLog Text)
forall i. DataLogger i -> StaticRep (DataLog i)
DataLog (DataLogger Text -> StaticRep (DataLog Text))
-> DataLogger Text -> StaticRep (DataLog Text)
forall a b. (a -> b) -> a -> b
$ (Text -> IO ()) -> DataLogger Text
forall i. (i -> IO ()) -> DataLogger i
DataLogger ((Text -> IO ()) -> DataLogger Text)
-> (Text -> IO ()) -> DataLogger Text
forall a b. (a -> b) -> a -> b
$ Handle -> Text -> IO ()
T.hPutStrLn Handle
h

runDataLogTextToStdout :: ()
  => HasCallStack
  => Eff (DataLog Text : r) a
  -> Eff r a
runDataLogTextToStdout :: forall (r :: [Effect]) a.
HasCallStack =>
Eff (DataLog Text : r) a -> Eff r a
runDataLogTextToStdout =
  Handle -> Eff (DataLog Text : r) a -> Eff r a
forall (r :: [Effect]) a.
HasCallStack =>
Handle -> Eff (DataLog Text : r) a -> Eff r a
runDataLogTextToHandle Handle
IO.stdout

runDataLogTextToStderr :: ()
  => HasCallStack
  => Eff (DataLog Text : r) a
  -> Eff r a
runDataLogTextToStderr :: forall (r :: [Effect]) a.
HasCallStack =>
Eff (DataLog Text : r) a -> Eff r a
runDataLogTextToStderr =
  Handle -> Eff (DataLog Text : r) a -> Eff r a
forall (r :: [Effect]) a.
HasCallStack =>
Handle -> Eff (DataLog Text : r) a -> Eff r a
runDataLogTextToHandle Handle
IO.stderr

withDataLogSerialiser :: ()
  => HasCallStack
  => (DataLogger i -> DataLogger o)
  -> Eff (DataLog o : r) a
  -> Eff (DataLog i : r) a
withDataLogSerialiser :: forall i o (r :: [Effect]) a.
HasCallStack =>
(DataLogger i -> DataLogger o)
-> Eff (DataLog o : r) a -> Eff (DataLog i : r) a
withDataLogSerialiser DataLogger i -> DataLogger o
f Eff (DataLog o : r) a
m = do
  DataLogger i
logger <- Eff (DataLog i : r) (DataLogger i)
forall (r :: [Effect]) i.
(HasCallStack, r <: DataLog i) =>
Eff r (DataLogger i)
getDataLogger
  let DataLogger i
_ = DataLogger i
logger
  Eff r a -> Eff (DataLog i : r) a
forall (es :: [Effect]) a (e :: Effect). Eff es a -> Eff (e : es) a
raise (Eff r a -> Eff (DataLog i : r) a)
-> Eff r a -> Eff (DataLog i : r) a
forall a b. (a -> b) -> a -> b
$ StaticRep (DataLog o) -> Eff (DataLog o : r) a -> Eff r a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
 MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep (DataLogger o -> StaticRep (DataLog o)
forall i. DataLogger i -> StaticRep (DataLog i)
DataLog (DataLogger i -> DataLogger o
f DataLogger i
logger)) Eff (DataLog o : r) a
m

withDataLog :: ()
  => HasCallStack
  => (o -> i)
  -> Eff (DataLog o : r) a
  -> Eff (DataLog i : r) a
withDataLog :: forall o i (r :: [Effect]) a.
HasCallStack =>
(o -> i) -> Eff (DataLog o : r) a -> Eff (DataLog i : r) a
withDataLog =
  (DataLogger i -> DataLogger o)
-> Eff (DataLog o : r) a -> Eff (DataLog i : r) a
forall i o (r :: [Effect]) a.
HasCallStack =>
(DataLogger i -> DataLogger o)
-> Eff (DataLog o : r) a -> Eff (DataLog i : r) a
withDataLogSerialiser ((DataLogger i -> DataLogger o)
 -> Eff (DataLog o : r) a -> Eff (DataLog i : r) a)
-> ((o -> i) -> DataLogger i -> DataLogger o)
-> (o -> i)
-> Eff (DataLog o : r) a
-> Eff (DataLog i : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (o -> i) -> DataLogger i -> DataLogger o
forall a' a. (a' -> a) -> DataLogger a -> DataLogger a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap

getDataLogger :: ()
  => HasCallStack
  => r <: DataLog i
  => Eff r (DataLogger i)
getDataLogger :: forall (r :: [Effect]) i.
(HasCallStack, r <: DataLog i) =>
Eff r (DataLogger i)
getDataLogger = do
  DataLog DataLogger i
i <- Eff r (StaticRep (DataLog i))
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect]).
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
Eff es (StaticRep e)
getStaticRep
  DataLogger i -> Eff r (DataLogger i)
forall a. a -> Eff r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DataLogger i
i

log :: ()
  => HasCallStack
  => r <: DataLog i
  => i
  -> Eff r ()
log :: forall (r :: [Effect]) i.
(HasCallStack, r <: DataLog i) =>
i -> Eff r ()
log i
i = do
  DataLogger i
dataLogger <- Eff r (DataLogger i)
forall (r :: [Effect]) i.
(HasCallStack, r <: DataLog i) =>
Eff r (DataLogger i)
getDataLogger
  IO () -> Eff r ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff r ()) -> IO () -> Eff r ()
forall a b. (a -> b) -> a -> b
$ DataLogger i
dataLogger.run i
i

local :: ()
  => HasCallStack
  => r <: DataLog i
  => (i -> i)
  -> Eff r a
  -> Eff r a
local :: forall (r :: [Effect]) i a.
(HasCallStack, r <: DataLog i) =>
(i -> i) -> Eff r a -> Eff r a
local i -> i
f =
  (StaticRep (DataLog i) -> StaticRep (DataLog i))
-> Eff r a -> Eff r a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects, e :> es) =>
(StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
localStaticRep ((StaticRep (DataLog i) -> StaticRep (DataLog i))
 -> Eff r a -> Eff r a)
-> (StaticRep (DataLog i) -> StaticRep (DataLog i))
-> Eff r a
-> Eff r a
forall a b. (a -> b) -> a -> b
$ \(DataLog DataLogger i
s) -> DataLogger i -> StaticRep (DataLog i)
forall i. DataLogger i -> StaticRep (DataLog i)
DataLog ((i -> i) -> DataLogger i -> DataLogger i
forall a' a. (a' -> a) -> DataLogger a -> DataLogger a'
forall (f :: * -> *) a' a.
Contravariant f =>
(a' -> a) -> f a -> f a'
contramap i -> i
f DataLogger i
s)