module Calamity.Commands.Check
( Check(..)
, buildCheck
, buildCheckPure
, runCheck ) where
import {-# SOURCE #-} Calamity.Commands.Context
import Calamity.Commands.Error
import Calamity.Internal.RunIntoIO
import Calamity.Internal.Utils
import Control.Lens hiding ( (<.>), Context )
import Data.Generics.Labels ()
import Data.Maybe
import qualified Data.Text as S
import qualified Data.Text.Lazy as L
import GHC.Generics
import qualified Polysemy as P
data Check = MkCheck
{ Check -> Text
name :: S.Text
, Check -> Context -> IO (Maybe Text)
callback :: Context -> IO (Maybe L.Text)
}
deriving ( (forall x. Check -> Rep Check x)
-> (forall x. Rep Check x -> Check) -> Generic Check
forall x. Rep Check x -> Check
forall x. Check -> Rep Check x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Check x -> Check
$cfrom :: forall x. Check -> Rep Check x
Generic )
buildCheck :: P.Member (P.Final IO) r => S.Text -> (Context -> P.Sem r (Maybe L.Text)) -> P.Sem r Check
buildCheck :: Text -> (Context -> Sem r (Maybe Text)) -> Sem r Check
buildCheck name :: Text
name cb :: Context -> Sem r (Maybe Text)
cb = do
Context -> IO (Maybe (Maybe Text))
cb' <- (Context -> Sem r (Maybe Text))
-> Sem r (Context -> IO (Maybe (Maybe Text)))
forall (r :: [(* -> *) -> * -> *]) p a.
Member (Final IO) r =>
(p -> Sem r a) -> Sem r (p -> IO (Maybe a))
bindSemToIO Context -> Sem r (Maybe Text)
cb
let cb'' :: Context -> IO (Maybe Text)
cb'' = Maybe Text -> Maybe (Maybe Text) -> Maybe Text
forall a. a -> Maybe a -> a
fromMaybe (Text -> Maybe Text
forall a. a -> Maybe a
Just "failed internally") (Maybe (Maybe Text) -> Maybe Text)
-> (Context -> IO (Maybe (Maybe Text)))
-> Context
-> IO (Maybe Text)
forall (f :: * -> *) a b c.
Functor f =>
(a -> b) -> (c -> f a) -> c -> f b
<.> Context -> IO (Maybe (Maybe Text))
cb'
Check -> Sem r Check
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Check -> Sem r Check) -> Check -> Sem r Check
forall a b. (a -> b) -> a -> b
$ Text -> (Context -> IO (Maybe Text)) -> Check
MkCheck Text
name Context -> IO (Maybe Text)
cb''
buildCheckPure :: S.Text -> (Context -> Maybe L.Text) -> Check
buildCheckPure :: Text -> (Context -> Maybe Text) -> Check
buildCheckPure name :: Text
name cb :: Context -> Maybe Text
cb = Text -> (Context -> IO (Maybe Text)) -> Check
MkCheck Text
name (Maybe Text -> IO (Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Text -> IO (Maybe Text))
-> (Context -> Maybe Text) -> Context -> IO (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Context -> Maybe Text
cb)
runCheck :: P.Member (P.Embed IO) r => Context -> Check -> P.Sem r (Either CommandError ())
runCheck :: Context -> Check -> Sem r (Either CommandError ())
runCheck ctx :: Context
ctx chk :: Check
chk = IO (Maybe Text) -> Sem r (Maybe Text)
forall (m :: * -> *) (r :: [(* -> *) -> * -> *]) a.
Member (Embed m) r =>
m a -> Sem r a
P.embed (Check -> Context -> IO (Maybe Text)
callback Check
chk Context
ctx) Sem r (Maybe Text)
-> (Maybe Text -> Either CommandError ())
-> Sem r (Either CommandError ())
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> Maybe CommandError -> Either CommandError ()
forall e. Maybe e -> Either e ()
justToEither (Maybe CommandError -> Either CommandError ())
-> (Maybe Text -> Maybe CommandError)
-> Maybe Text
-> Either CommandError ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text -> CommandError
CheckError (Check
chk Check -> Getting Text Check Text -> Text
forall s a. s -> Getting a s a -> a
^. IsLabel "name" (Getting Text Check Text)
Getting Text Check Text
#name) (Text -> CommandError) -> Maybe Text -> Maybe CommandError
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>)