{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
module Effectful.Notify.Static
(
Notify,
initNotifyEnv,
notify,
runNotify,
NotifyInitException (..),
NotifyException (..),
catchNonFatalNotify,
tryNonFatalNotify,
tryNonFatalNotify_,
NotifySystem.NotifySystemOs (..),
defaultNotifySystemOs,
NotifySystem (..),
defaultNotifySystem,
notifySystemToOs,
notifySystemFromOs,
Os (..),
NotifyParseException (..),
NotifyEnv,
notifyEnvToSystemOs,
Note,
mkNote,
setBody,
getBody,
setSummary,
getSummary,
setTimeout,
getTimeout,
setTitle,
getTitle,
setUrgency,
getUrgency,
NotifyTimeout (..),
_NotifyTimeoutMillis,
_NotifyTimeoutNever,
NotifyUrgency (..),
_NotifyUrgencyLow,
_NotifyUrgencyNormal,
_NotifyUrgencyCritical,
)
where
import Control.Monad (void)
import Control.Monad.Catch qualified as C
import Effectful
( Dispatch (Static),
DispatchOf,
Eff,
Effect,
IOE,
type (:>),
)
import Effectful.Dispatch.Static
( HasCallStack,
SideEffects (WithSideEffects),
StaticRep,
evalStaticRep,
unsafeEff_,
)
import Effectful.Notify.Internal.Data.Note
( Note,
getBody,
getSummary,
getTimeout,
getTitle,
getUrgency,
mkNote,
setBody,
setSummary,
setTimeout,
setTitle,
setUrgency,
)
import Effectful.Notify.Internal.Data.NotifyEnv (NotifyEnv, notifyEnvToSystemOs)
import Effectful.Notify.Internal.Data.NotifyException
( NotifyException (MkNotifyException, exception, fatal, note, notifySystem),
)
import Effectful.Notify.Internal.Data.NotifyInitException
( NotifyInitException (MkNotifyInitException, unNotifyInitException),
)
import Effectful.Notify.Internal.Data.NotifySystem
( NotifyParseException (MkNotifyParseException, os, system),
NotifySystem
( NotifySystemAppleScript,
NotifySystemDBus,
NotifySystemNotifySend,
NotifySystemWindows
),
NotifySystemOs,
defaultNotifySystem,
defaultNotifySystemOs,
notifySystemFromOs,
notifySystemToOs,
)
import Effectful.Notify.Internal.Data.NotifySystem qualified as NotifySystem
import Effectful.Notify.Internal.Data.NotifyTimeout
( NotifyTimeout (NotifyTimeoutMillis, NotifyTimeoutNever),
_NotifyTimeoutMillis,
_NotifyTimeoutNever,
)
import Effectful.Notify.Internal.Data.NotifyUrgency
( NotifyUrgency (NotifyUrgencyCritical, NotifyUrgencyLow, NotifyUrgencyNormal),
_NotifyUrgencyCritical,
_NotifyUrgencyLow,
_NotifyUrgencyNormal,
)
import Effectful.Notify.Internal.Os (Os (Linux, Osx, Windows))
#if LINUX
import Effectful.Notify.Internal.Os.Linux qualified as Os
#elif OSX
import Effectful.Notify.Internal.Os.Osx qualified as Os
#else
import Effectful.Notify.Internal.Os.Windows qualified as Os
#endif
import Optics.Core ((^.))
data Notify :: Effect
type instance DispatchOf Notify = Static WithSideEffects
data instance StaticRep Notify = MkNotify
runNotify ::
forall es a.
( HasCallStack,
IOE :> es
) =>
Eff (Notify : es) a ->
Eff es a
runNotify :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
Eff (Notify : es) a -> Eff es a
runNotify = StaticRep Notify -> Eff (Notify : es) a -> Eff es 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 Notify
MkNotify
initNotifyEnv ::
forall es.
( HasCallStack,
Notify :> es
) =>
NotifySystemOs ->
Eff es NotifyEnv
initNotifyEnv :: forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifySystemOs -> Eff es NotifyEnv
initNotifyEnv = IO NotifyEnv -> Eff es NotifyEnv
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO NotifyEnv -> Eff es NotifyEnv)
-> (NotifySystemOs -> IO NotifyEnv)
-> NotifySystemOs
-> Eff es NotifyEnv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => NotifySystemOs -> IO NotifyEnv
NotifySystemOs -> IO NotifyEnv
Os.initNotifyEnv
notify ::
forall es.
( HasCallStack,
Notify :> es
) =>
NotifyEnv ->
Note ->
Eff es ()
notify :: forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifyEnv -> Note -> Eff es ()
notify NotifyEnv
env = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ()) -> (Note -> IO ()) -> Note -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NotifyEnv -> Note -> IO ()
Os.notify NotifyEnv
env
catchNonFatalNotify ::
forall es.
( HasCallStack,
Notify :> es
) =>
NotifyEnv ->
Note ->
(NotifyException -> Eff es ()) ->
Eff es ()
catchNonFatalNotify :: forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifyEnv -> Note -> (NotifyException -> Eff es ()) -> Eff es ()
catchNonFatalNotify NotifyEnv
env Note
note NotifyException -> Eff es ()
handler =
NotifyEnv -> Note -> Eff es ()
forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifyEnv -> Note -> Eff es ()
notify NotifyEnv
env Note
note Eff es () -> (NotifyException -> Eff es ()) -> Eff es ()
forall e a.
(HasCallStack, Exception e) =>
Eff es a -> (e -> Eff es a) -> Eff es a
forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
m a -> (e -> m a) -> m a
`C.catch` \NotifyException
ne ->
if NotifyException
ne NotifyException -> Optic' A_Lens NoIx NotifyException Bool -> Bool
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx NotifyException Bool
#fatal
then NotifyException -> Eff es ()
forall e a. (HasCallStack, Exception e) => e -> Eff es a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
C.throwM NotifyException
ne
else NotifyException -> Eff es ()
handler NotifyException
ne
tryNonFatalNotify ::
forall es.
( HasCallStack,
Notify :> es
) =>
NotifyEnv ->
Note ->
Eff es (Maybe NotifyException)
tryNonFatalNotify :: forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifyEnv -> Note -> Eff es (Maybe NotifyException)
tryNonFatalNotify NotifyEnv
env Note
note =
Eff es () -> Eff es (Either NotifyException ())
forall (m :: * -> *) e a.
(HasCallStack, MonadCatch m, Exception e) =>
m a -> m (Either e a)
C.try (NotifyEnv -> Note -> Eff es ()
forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifyEnv -> Note -> Eff es ()
notify NotifyEnv
env Note
note) Eff es (Either NotifyException ())
-> (Either NotifyException () -> Eff es (Maybe NotifyException))
-> Eff es (Maybe NotifyException)
forall a b. Eff es a -> (a -> Eff es b) -> Eff es b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left NotifyException
ex ->
if NotifyException
ex NotifyException -> Optic' A_Lens NoIx NotifyException Bool -> Bool
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx NotifyException Bool
#fatal
then NotifyException -> Eff es (Maybe NotifyException)
forall e a. (HasCallStack, Exception e) => e -> Eff es a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
C.throwM NotifyException
ex
else Maybe NotifyException -> Eff es (Maybe NotifyException)
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe NotifyException -> Eff es (Maybe NotifyException))
-> Maybe NotifyException -> Eff es (Maybe NotifyException)
forall a b. (a -> b) -> a -> b
$ NotifyException -> Maybe NotifyException
forall a. a -> Maybe a
Just NotifyException
ex
Right ()
_ -> Maybe NotifyException -> Eff es (Maybe NotifyException)
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe NotifyException
forall a. Maybe a
Nothing
tryNonFatalNotify_ ::
forall es.
( HasCallStack,
Notify :> es
) =>
NotifyEnv ->
Note ->
Eff es ()
tryNonFatalNotify_ :: forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifyEnv -> Note -> Eff es ()
tryNonFatalNotify_ NotifyEnv
env = Eff es (Maybe NotifyException) -> Eff es ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Eff es (Maybe NotifyException) -> Eff es ())
-> (Note -> Eff es (Maybe NotifyException)) -> Note -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NotifyEnv -> Note -> Eff es (Maybe NotifyException)
forall (es :: [Effect]).
(HasCallStack, Notify :> es) =>
NotifyEnv -> Note -> Eff es (Maybe NotifyException)
tryNonFatalNotify NotifyEnv
env