calamity 0.1.15.0 → 0.1.16.0
raw patch · 6 files changed
+58/−47 lines, 6 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Calamity.Commands.Dsl: fetchHandler :: Sem (DSLState r) CommandHandler
+ Calamity.Commands.Utils: CommandInvokeError :: Context -> CommandError -> CmdInvokeFailReason
+ Calamity.Commands.Utils: NoContext :: CmdInvokeFailReason
+ Calamity.Commands.Utils: NotFound :: [Text] -> CmdInvokeFailReason
+ Calamity.Commands.Utils: data CmdInvokeFailReason
- Calamity.Commands.Utils: handleCommands :: (BotC r, Member ParsePrefix r) => CommandHandler -> Message -> Text -> Text -> Sem r ()
+ Calamity.Commands.Utils: handleCommands :: (BotC r, Member ParsePrefix r) => CommandHandler -> Message -> Text -> Text -> Sem r (Either CmdInvokeFailReason Context)
Files
- ChangeLog.md +8/−0
- README.md +5/−4
- calamity.cabal +3/−3
- src/Calamity/Commands.hs +1/−1
- src/Calamity/Commands/Dsl.hs +6/−1
- src/Calamity/Commands/Utils.hs +35/−38
ChangeLog.md view
@@ -1,5 +1,13 @@ # Changelog for Calamity +## 0.1.16.0++* Change how commands should be manually invoked from code, instead of firing a+ `"invoke-command"` custom event, now the `handleCommands` function should be+ used, which returns information about if the command succeeded.+ +* Added `fetchHandler` for retrieving the command handler inside a command DSL.+ ## 0.1.15.0 * General cleanup of codebase
README.md view
@@ -30,12 +30,13 @@ # Docs -You can find documentation on hackage: [here](https://hackage.haskell.org/package/calamity)+You can find documentation on hackage at: https://hackage.haskell.org/package/calamity -# Example+# Examples -An example project can be found at:-[nitros12/calamity-example](https://github.com/nitros12/calamity-example)+Some example projects can be found at:+- [nitros12/calamity-example](https://github.com/nitros12/calamity-example): An extended example of the snippet below, shows use of metrics.+- [nitros12/calamity-bot](https://github.com/nitros12/calamity-bot): Uses a database, showing modularisation of groups/commands. ``` haskell {-# LANGUAGE DataKinds #-}
calamity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 4b15c9b738742337c0b66ea62dee6c54be20a41b9161fe630a70cf58dddf1d1c+-- hash: 7fb5885fd8780fbb721679f8e2823047e0bea244a686ec69115ca4b56159f700 name: calamity-version: 0.1.15.0+version: 0.1.16.0 synopsis: A library for writing discord bots in haskell description: Please see the README on GitHub at <https://github.com/nitros12/calamity#readme> category: Network, Web@@ -134,7 +134,7 @@ Paths_calamity hs-source-dirs: src- default-extensions: StrictData CPP AllowAmbiguousTypes BlockArguments NoMonomorphismRestriction BangPatterns BinaryLiterals UndecidableInstances ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DoAndIfThenElse EmptyDataDecls ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs DerivingVia DerivingStrategies GeneralizedNewtypeDeriving StandaloneDeriving DeriveAnyClass InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns OverloadedStrings OverloadedLabels PartialTypeSignatures PatternGuards PolyKinds RankNTypes RecordWildCards ScopedTypeVariables TupleSections TypeFamilies TypeSynonymInstances ViewPatterns DuplicateRecordFields TypeOperators TypeApplications RoleAnnotations+ default-extensions: StrictData AllowAmbiguousTypes BlockArguments NoMonomorphismRestriction BangPatterns BinaryLiterals UndecidableInstances ConstraintKinds DataKinds DefaultSignatures DeriveDataTypeable DeriveFoldable DeriveFunctor DeriveGeneric DeriveTraversable DoAndIfThenElse EmptyDataDecls ExistentialQuantification FlexibleContexts FlexibleInstances FunctionalDependencies GADTs DerivingVia DerivingStrategies GeneralizedNewtypeDeriving StandaloneDeriving DeriveAnyClass InstanceSigs KindSignatures LambdaCase MultiParamTypeClasses MultiWayIf NamedFieldPuns OverloadedStrings OverloadedLabels PartialTypeSignatures PatternGuards PolyKinds RankNTypes RecordWildCards ScopedTypeVariables TupleSections TypeFamilies TypeSynonymInstances ViewPatterns DuplicateRecordFields TypeOperators TypeApplications RoleAnnotations ghc-options: -fwrite-ide-info -hiedir=.hie -fplugin=Polysemy.Plugin -funbox-strict-fields -Wall -fno-warn-name-shadowing build-depends: aeson >=1.4 && <2
src/Calamity/Commands.hs view
@@ -46,7 +46,7 @@ -- -- Fired when a command returns an error. ----- 2. @"command-not-found" ['Data.Text.Lazy.Text']@+-- 2. @"command-not-found" ('Calamity.Types.Model.Channel.Message', '['Data.Text.Lazy.Text'])@ -- -- Fired when a valid prefix is used, but the command is not found. --
src/Calamity/Commands/Dsl.hs view
@@ -15,7 +15,8 @@ , groupA , groupA' , DSLState- , raiseDSL ) where+ , raiseDSL+ , fetchHandler ) where import Calamity.Commands.AliasType import Calamity.Commands.Check@@ -247,3 +248,7 @@ ltell $ LH.singleton name (group', Original) ltell $ LH.fromList [(name, (group', Alias)) | name <- aliases] pure res++-- | Retrieve the final command handler for this block+fetchHandler :: P.Sem (DSLState r) CommandHandler+fetchHandler = P.ask
src/Calamity/Commands/Utils.hs view
@@ -5,7 +5,8 @@ , buildCommands , buildContext , handleCommands- , findCommand ) where+ , findCommand+ , CmdInvokeFailReason(..) ) where import Calamity.Cache.Eff import Calamity.Metrics.Eff@@ -45,32 +46,15 @@ mapLeft f (Left x) = Left $ f x mapLeft _ (Right x) = Right x -data FailReason- = NoCtx- | NF [L.Text]- | ERR Context CommandError+data CmdInvokeFailReason+ = NoContext+ | NotFound [L.Text]+ | CommandInvokeError Context CommandError -- | Construct commands and groups from a command DSL, then registers an event -- handler on the bot that manages running those commands. ----- This registers the following event handler for: @"invoke-command" ('Message',--- 'L.Text')@ that takes a message and the command string to invoke (without a--- prefix)------ Returns an action to remove the event handler, and the 'CommandHandler' that was constructed-addCommands :: (BotC r, P.Member ParsePrefix r) => P.Sem (DSLState r) a -> P.Sem r (P.Sem r (), CommandHandler, a)-addCommands m = do- (handler, res) <- buildCommands m- remove <- react @'MessageCreateEvt $ \msg -> do- parsePrefix msg >>= \case- Just (prefix, cmd) ->- handleCommands handler msg prefix cmd- Nothing -> pure ()- remove' <- react @('CustomEvt "invoke-command" (Message, L.Text)) $ \(msg, cmd) -> do- handleCommands handler msg "" cmd- pure (remove *> remove', handler, res)---- | Manages parsing messages and handling commands for a CommandHandler.+-- Returns an action to remove the event handler, and the 'CommandHandler' that was constructed. -- -- ==== Custom Events --@@ -80,7 +64,7 @@ -- -- Fired when a command returns an error. ----- 2. @"command-not-found" ['Data.Text.Lazy.Text']@+-- 2. @"command-not-found" ('Calamity.Types.Model.Channel.Message', '['Data.Text.Lazy.Text'])@ -- -- Fired when a valid prefix is used, but the command is not found. --@@ -88,26 +72,39 @@ -- -- Fired when a command is successfully invoked. --+addCommands :: (BotC r, P.Member ParsePrefix r) => P.Sem (DSLState r) a -> P.Sem r (P.Sem r (), CommandHandler, a)+addCommands m = do+ (handler, res) <- buildCommands m+ remove <- react @'MessageCreateEvt $ \msg -> do+ parsePrefix msg >>= \case+ Just (prefix, cmd) -> do+ r <- handleCommands handler msg prefix cmd+ case r of+ Left (CommandInvokeError ctx e) -> fire $ customEvt @"command-error" (ctx, e)+ Left (NotFound path) -> fire $ customEvt @"command-not-found" (msg, path)+ Left NoContext -> pure () -- ignore if context couldn't be built+ Right ctx -> do+ cmdInvoke <- registerCounter "commands_invoked" [("name", S.unwords $ commandPath (ctx ^. #command))]+ void $ addCounter 1 cmdInvoke+ fire $ customEvt @"command-invoked" ctx+ Nothing -> pure ()+ pure (remove, handler, res)++-- | Manages parsing messages and handling commands for a CommandHandler.+--+-- Returns Right if the command succeeded in parsing and running, Left with the+-- reason otherwise. handleCommands :: (BotC r, P.Member ParsePrefix r) => CommandHandler -> Message -- ^ The message that invoked the command -> L.Text -- ^ The prefix used -> L.Text -- ^ The command string, without a prefix- -> P.Sem r ()-handleCommands handler msg prefix cmd = do- err <- P.runError $ do- (command, unparsedParams) <- P.fromEither $ mapLeft NF $ findCommand handler cmd- ctx <- P.note NoCtx =<< buildContext msg prefix command unparsedParams- P.fromEither . mapLeft (ERR ctx) =<< invokeCommand ctx (ctx ^. #command)+ -> P.Sem r (Either CmdInvokeFailReason Context)+handleCommands handler msg prefix cmd = P.runError $ do+ (command, unparsedParams) <- P.fromEither $ mapLeft NotFound $ findCommand handler cmd+ ctx <- P.note NoContext =<< buildContext msg prefix command unparsedParams+ P.fromEither . mapLeft (CommandInvokeError ctx) =<< invokeCommand ctx (ctx ^. #command) pure ctx- case err of- Left (ERR ctx e) -> fire $ customEvt @"command-error" (ctx, e)- Left (NF path) -> fire $ customEvt @"command-not-found" path- Left _ -> pure () -- ignore if no prefix or if context couldn't be built- Right ctx -> do- cmdInvoke <- registerCounter "commands_invoked" [("name", S.unwords $ commandPath (ctx ^. #command))]- void $ addCounter 1 cmdInvoke- fire $ customEvt @"command-invoked" ctx -- | Run a command DSL, returning the constructed 'CommandHandler'