packages feed

calamity-commands 0.1.3.0 → 0.2.0.0

raw patch · 15 files changed

+219/−213 lines, 15 filesdep ~polysemy-plugindep ~textPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: polysemy-plugin, text

API changes (from Hackage documentation)

- CalamityCommands.Context: constructContext :: forall msg_aFlx ctx_aFlv m'_aFlu a'_aFlw r_aFo7. MemberWithError (ConstructContext msg_aFlx ctx_aFlv m'_aFlu a'_aFlw) r_aFo7 => (Text, Command m'_aFlu ctx_aFlv a'_aFlw, Text) -> msg_aFlx -> Sem r_aFo7 (Maybe ctx_aFlv)
+ CalamityCommands.Context: constructContext :: forall msg_aF5w ctx_aF5u m'_aF5t a'_aF5v r_aF86. Member (ConstructContext msg_aF5w ctx_aF5u m'_aF5t a'_aF5v) r_aF86 => (Text, Command m'_aF5t ctx_aF5u a'_aF5v, Text) -> msg_aF5w -> Sem r_aF86 (Maybe ctx_aF5u)
- CalamityCommands.Internal.LocalWriter: llisten :: forall o_ajsg r_ajDx a_Xjsg. MemberWithError (LocalWriter o_ajsg) r_ajDx => Sem r_ajDx a_Xjsg -> Sem r_ajDx (o_ajsg, a_Xjsg)
+ CalamityCommands.Internal.LocalWriter: llisten :: forall o_ajlk r_ajwB a_Xjlk. Member (LocalWriter o_ajlk) r_ajwB => Sem r_ajwB a_Xjlk -> Sem r_ajwB (o_ajlk, a_Xjlk)
- CalamityCommands.Internal.LocalWriter: ltell :: forall o_ajsc r_ajDv. MemberWithError (LocalWriter o_ajsc) r_ajDv => o_ajsc -> Sem r_ajDv ()
+ CalamityCommands.Internal.LocalWriter: ltell :: forall o_ajlg r_ajwz. Member (LocalWriter o_ajlg) r_ajwz => o_ajlg -> Sem r_ajwz ()
- CalamityCommands.ParsePrefix: parsePrefix :: forall msg_aG9X r_aGaN. MemberWithError (ParsePrefix msg_aG9X) r_aGaN => msg_aG9X -> Sem r_aGaN (Maybe (Text, Text))
+ CalamityCommands.ParsePrefix: parsePrefix :: forall msg_aFSM r_aFTC. Member (ParsePrefix msg_aFSM) r_aFTC => msg_aFSM -> Sem r_aFTC (Maybe (Text, Text))

Files

CalamityCommands.hs view
@@ -65,7 +65,7 @@  handler is generic over the context used:   @- h' :: 'CommandContext' 'Data.Functor.Identity.Identity' c ('Either' 'Data.Text.Lazy.Text' 'Int') => 'CommandHandler' 'Data.Functor.Identity.Identity' c ('Either' 'Data.Text.Lazy.Text' 'Int')+ h' :: 'CommandContext' 'Data.Functor.Identity.Identity' c ('Either' 'Data.Text.Text' 'Int') => 'CommandHandler' 'Data.Functor.Identity.Identity' c ('Either' 'Data.Text.Text' 'Int')  h' = 'Data.Functor.Identity.runIdentity' . 'Polysemy.runFinal' $ do    (h, _) <- 'buildCommands' $ do      'command' \@\'[Int, Int] "add" $ \ctx a b -> 'pure' $ 'Right' (a '+' b)@@ -91,9 +91,9 @@  the invoked command and runs it, returning the result.   @- r :: 'Data.Text.Lazy.Text' -> 'Maybe' ('Either'-                     ('CmdInvokeFailReason' ('BasicContext' 'Data.Functor.Identity.Identity' ('Either' 'Data.Text.Lazy.Text' 'Int')))-                     ('BasicContext' 'Data.Functor.Identity.Identity' ('Either' 'Data.Text.Lazy.Text' 'Int'), 'Either' 'Data.Text.Lazy.Text' 'Int'))+ r :: 'Data.Text.Text' -> 'Maybe' ('Either'+                     ('CmdInvokeFailReason' ('BasicContext' 'Data.Functor.Identity.Identity' ('Either' 'Data.Text.Text' 'Int')))+                     ('BasicContext' 'Data.Functor.Identity.Identity' ('Either' 'Data.Text.Text' 'Int'), 'Either' 'Data.Text.Text' 'Int'))  r = 'Data.Functor.Identity.runIdentity' . 'Polysemy.runFinal' . 'Polysemy.embedToFinal' . 'useBasicContext' . 'useConstantPrefix' "!" . 'processCommands' h'  @ @@ -102,16 +102,16 @@  invoked successfully, and prints the error nicely if not.   @- rm :: 'Data.Text.Lazy.Text' -> IO ()+ rm :: 'Data.Text.Text' -> IO ()  rm s = case r s of              Just (Right (_, Right r)) ->              print r               Just (Right (_, Left h)) ->-             'Data.Text.Lazy.IO.putStrLn' h+             'Data.Text.IO.putStrLn' h               Just (Left ('CommandInvokeError' _ ('ParseError' t r))) ->-             'Data.Text.Lazy.IO.putStrLn' ("Parsing parameter " '<>' 'Data.Text.Lazy.fromStrict' t '<>' " failed with reason: " '<>' r)+             'Data.Text.IO.putStrLn' ("Parsing parameter " '<>' t '<>' " failed with reason: " '<>' r)                _ -> pure ()  @
CalamityCommands/Check.hs view
@@ -14,8 +14,7 @@  import Data.Generics.Labels () import Data.Maybe-import qualified Data.Text as S-import qualified Data.Text.Lazy as L+import qualified Data.Text as T  import GHC.Generics @@ -27,24 +26,24 @@ -} data Check m c = MkCheck     { -- | The name of the check.-      name :: S.Text+      name :: T.Text     , -- | The callback for the check, returns Nothing if it passes, otherwise       -- returns the reason for it not passing.-      callback :: c -> m (Maybe L.Text)+      callback :: c -> m (Maybe T.Text)     }     deriving (Generic)  {- | Given the name of a check and a callback in the 'P.Sem' monad, build a check  by transforming the Polysemy action into an @m@ action. -}-buildCheck :: (Monad m, P.Member (P.Final m) r) => S.Text -> (c -> P.Sem r (Maybe L.Text)) -> P.Sem r (Check m c)+buildCheck :: (Monad m, P.Member (P.Final m) r) => T.Text -> (c -> P.Sem r (Maybe T.Text)) -> P.Sem r (Check m c) buildCheck name cb = do     cb' <- bindSemToM cb     let cb'' = fromMaybe (Just "failed internally") <.> cb'     pure $ MkCheck name cb''  -- | Given the name of a check and a pure callback function, build a check.-buildCheckPure :: Monad m => S.Text -> (c -> Maybe L.Text) -> Check m c+buildCheckPure :: Monad m => T.Text -> (c -> Maybe T.Text) -> Check m c buildCheckPure name cb = MkCheck name (pure . cb)  {- | Given an invokation context @c@, run a check and transform the result into an
CalamityCommands/Command.hs view
@@ -12,8 +12,7 @@  import Data.Kind (Type) import Data.List.NonEmpty (NonEmpty)-import Data.Text as S-import Data.Text.Lazy as L+import Data.Text as T  import GHC.Generics @@ -21,10 +20,10 @@ import TextShow import qualified TextShow.Generic as TSG --- | A command, paremeterised over it's context+-- | A command, paremeterised over its context data Command (m :: Type -> Type) (c :: Type) (a :: Type) = forall p.   Command-  { names :: NonEmpty S.Text+  { names :: NonEmpty T.Text   , parent :: Maybe (Group m c a)   , -- | If this command is hidden     hidden :: Bool@@ -33,20 +32,20 @@   , -- | A list of parameter metadata     params :: [ParameterInfo]   , -- | A function producing the \'help\' for the command.-    help :: c -> L.Text+    help :: c -> T.Text   , -- | A function that parses the context for the command, producing the input     -- @a@ for the command.     parser :: c -> m (Either CommandError p)   , -- | A function that given the context and the input (@p@) of the command,     -- performs the action of the command.-    callback :: (c, p) -> m (Either L.Text a)+    callback :: (c, p) -> m (Either T.Text a)   }  data CommandS = CommandS-  { names :: NonEmpty S.Text+  { names :: NonEmpty T.Text   , params :: [ParameterInfo]-  , parent :: Maybe S.Text-  , checks :: [S.Text]+  , parent :: Maybe T.Text+  , checks :: [T.Text]   , hidden :: Bool   }   deriving (Generic, Show)
CalamityCommands/CommandUtils.hs view
@@ -32,7 +32,6 @@ import qualified Data.List.NonEmpty as NE import Data.Maybe import qualified Data.Text as S-import qualified Data.Text.Lazy as L  import qualified Polysemy as P import qualified Polysemy.Error as P@@ -45,7 +44,7 @@ commandPath Command{names, parent} = foldMap groupPath parent <> [NE.head names]  -- | Format a command's parameters-commandParams :: Command m c a -> L.Text+commandParams :: Command m c a -> S.Text commandParams Command{params} =   let formatted =         map@@ -53,7 +52,7 @@               "`" <> name <> ":" <> S.pack (show type_) <> "`"           )           params-   in L.fromStrict $ S.intercalate ", " formatted+   in S.intercalate ", " formatted  {- | Given the properties of a 'Command' with the @parser@ and @callback@ in the  'P.Sem' monad, build a command by transforming the Polysemy actions into @m@@@ -73,7 +72,7 @@   -- | The command's parameter metadata   [ParameterInfo] ->   -- | The help generator for this command-  (c -> L.Text) ->+  (c -> S.Text) ->   -- | The parser for this command   (c -> P.Sem r (Either CommandError p)) ->   -- | The callback for this command@@ -110,7 +109,7 @@   -- | The checks for the command   [Check m c] ->   -- | The help generator for this command-  (c -> L.Text) ->+  (c -> S.Text) ->   -- | The callback foor this command   (c -> CommandForParsers ps r a) ->   P.Sem r (Command m c a)@@ -136,9 +135,9 @@  transforming the Polysemy action into an @m@ action. -} buildCallback ::-  (Monad m, P.Member (P.Final m) r) => ((c, p) -> P.Sem (P.Fail ': r) a) -> P.Sem r ((c, p) -> m (Either L.Text a))+  (Monad m, P.Member (P.Final m) r) => ((c, p) -> P.Sem (P.Fail ': r) a) -> P.Sem r ((c, p) -> m (Either S.Text a)) buildCallback cb = do-  cb' <- bindSemToM (\x -> P.runFail (cb x) <&> mapLeft L.pack)+  cb' <- bindSemToM (\x -> P.runFail (cb x) <&> mapLeft S.pack)   let cb'' = fromMaybe (Left "failed internally") <.> cb'   pure cb'' @@ -207,7 +206,7 @@   forall (ps :: [Type]) c r.   ParameterParser (ListToTup ps) c r =>   c ->-  L.Text ->+  S.Text ->   P.Sem r (Either CommandError (ParserResult (ListToTup ps))) buildTypedCommandParser ctx t =   runCommandParser ctx t (parse @(ListToTup ps) @c @r) <&> \case@@ -224,8 +223,8 @@  As an example:   @- 'CommandForParsers' [ 'L.Text', 'Int', 'CalamityCommands.Parser.Named' "something" 'L.Text' ] r a ~-   ('L.Text' -> 'Int' -> 'L.Text' -> 'P.Sem' r ('P.Fail' ': r) a)+ 'CommandForParsers' [ 'S.Text', 'Int', 'CalamityCommands.Parser.Named' "something" 'S.Text' ] r a ~+   ('S.Text' -> 'Int' -> 'S.Text' -> 'P.Sem' r ('P.Fail' ': r) a)  @ -} type family CommandForParsers (ps :: [Type]) r a where
CalamityCommands/Context.hs view
@@ -9,7 +9,7 @@   useBasicContext, ) where -import qualified Data.Text.Lazy as L+import qualified Data.Text as T import GHC.Generics (Generic) import qualified Polysemy as P @@ -17,13 +17,13 @@  class CommandContext m c a | c -> m, c -> a where   -- | The prefix that was used to invoke the command-  ctxPrefix :: c -> L.Text+  ctxPrefix :: c -> T.Text    -- | The command that was invoked   ctxCommand :: c -> Command m c a    -- | The message remaining after consuming the prefix-  ctxUnparsedParams :: c -> L.Text+  ctxUnparsedParams :: c -> T.Text  -- | An effect for constructing the context for a command data ConstructContext msg ctx m' a' m a where@@ -31,7 +31,7 @@   -- success, or Nothing if a context could not be constructed   ConstructContext ::     -- | The (prefix, command, remaining)-    (L.Text, Command m' ctx a', L.Text) ->+    (T.Text, Command m' ctx a', T.Text) ->     -- | The message type to extract the context from     msg ->     ConstructContext msg ctx m' a' m (Maybe ctx)@@ -40,9 +40,9 @@  -- | A basic context that only knows the prefix used and the unparsed input data BasicContext m a = BasicContext-  { bcPrefix :: L.Text+  { bcPrefix :: T.Text   , bcCommand :: Command m (BasicContext m a) a-  , bcUnparsedParams :: L.Text+  , bcUnparsedParams :: T.Text   }   deriving (Show, Generic) 
CalamityCommands/Dsl.hs view
@@ -34,8 +34,7 @@ import CalamityCommands.Internal.LocalWriter  import qualified Data.HashMap.Lazy as LH-import qualified Data.Text as S-import qualified Data.Text.Lazy as L+import qualified Data.Text as T  import Data.List.NonEmpty (NonEmpty (..)) import qualified Polysemy as P@@ -63,12 +62,12 @@    'command' \@\'[] "test" \\ctx -> 'pure' ()  @ - In the above block, any command declared inside 'hide' will have it's+ In the above block, any command declared inside 'hide' will have its  \'hidden\' flag set and will not be shown by the default help command:  'CalamityCommands.Help.helpCommand'   The 'CalamityCommands.Help.helpCommand' function can be used to create a- help command for the commands DSL action it is used in, read it's doc page+ help command for the commands DSL action it is used in, read its doc page  for more information on how it functions.   The 'CalamityCommands.Utils.buildCommands' function is used to@@ -78,12 +77,12 @@ -}  type DSLState m c a r =-    ( LocalWriter (LH.HashMap S.Text (Command m c a, AliasType))-        ': LocalWriter (LH.HashMap S.Text (Group m c a, AliasType))+    ( LocalWriter (LH.HashMap T.Text (Command m c a, AliasType))+        ': LocalWriter (LH.HashMap T.Text (Group m c a, AliasType))             ': P.Reader (Maybe (Group m c a))                 ': P.Tagged "hidden" (P.Reader Bool)-                    ': P.Reader (c -> L.Text)-                        ': P.Tagged "original-help" (P.Reader (c -> L.Text))+                    ': P.Reader (c -> T.Text)+                        ': P.Tagged "original-help" (P.Reader (c -> T.Text))                             ': P.Reader [Check m c]                                 ': P.Reader (CommandHandler m c a)                                     ': P.Fixpoint@@ -103,7 +102,7 @@ command' ::     (Monad m, P.Member (P.Final m) r) =>     -- | The name of the command-    S.Text ->+    T.Text ->     -- | The command's parameter metadata     [ParameterInfo] ->     -- | The parser for this command@@ -124,9 +123,9 @@     forall p c a m r.     (Monad m, P.Member (P.Final m) r) =>     -- | The name of the command-    S.Text ->+    T.Text ->     -- | The aliases for the command-    [S.Text] ->+    [T.Text] ->     -- | The command's parameter metadata     [ParameterInfo] ->     -- | The parser for this command@@ -138,7 +137,7 @@     parent <- P.ask @(Maybe (Group m c a))     hidden <- P.tag $ P.ask @Bool     checks <- P.ask @[Check m c]-    help' <- P.ask @(c -> L.Text)+    help' <- P.ask @(c -> T.Text)     cmd <- raiseDSL $ buildCommand' (name :| aliases) parent hidden checks params help' parser cb     ltell $ LH.singleton name (cmd, Original)     ltell $ LH.fromList [(name, (cmd, Alias)) | name <- aliases]@@ -172,7 +171,7 @@     , CommandContext m c a     ) =>     -- | The name of the command-    S.Text ->+    T.Text ->     -- | The callback for this command     (c -> CommandForParsers ps r a) ->     P.Sem (DSLState m c a r) (Command m c a)@@ -202,9 +201,9 @@     , CommandContext m c a     ) =>     -- | The name of the command-    S.Text ->+    T.Text ->     -- | The aliases for the command-    [S.Text] ->+    [T.Text] ->     -- | The callback for this command     (c -> CommandForParsers ps r a) ->     P.Sem (DSLState m c a r) (Command m c a)@@ -212,7 +211,7 @@     parent <- P.ask @(Maybe (Group m c a))     hidden <- P.tag $ P.ask @Bool     checks <- P.ask @[Check m c]-    help' <- P.ask @(c -> L.Text)+    help' <- P.ask @(c -> T.Text)     cmd' <- raiseDSL $ buildCommand @ps (name :| aliases) parent hidden checks help' cmd     ltell $ LH.singleton name (cmd', Original)     ltell $ LH.fromList [(name, (cmd', Alias)) | name <- aliases]@@ -238,8 +237,8 @@  @ -} help ::-    P.Member (P.Reader (c -> L.Text)) r =>-    (c -> L.Text) ->+    P.Member (P.Reader (c -> T.Text)) r =>+    (c -> T.Text) ->     P.Sem r a ->     P.Sem r a help = P.local . const@@ -261,9 +260,9 @@ requires' ::     (Monad m, P.Member (P.Final m) r) =>     -- | The name of the check-    S.Text ->+    T.Text ->     -- | The callback for the check-    (c -> P.Sem r (Maybe L.Text)) ->+    (c -> P.Sem r (Maybe T.Text)) ->     P.Sem (DSLState m c a r) x ->     P.Sem (DSLState m c a r) x requires' name cb m = do@@ -285,7 +284,7 @@ -} requiresPure ::     Monad m =>-    [(S.Text, c -> Maybe L.Text)] ->+    [(T.Text, c -> Maybe T.Text)] ->     -- A list of check names and check callbacks     P.Sem (DSLState m c a r) x ->     P.Sem (DSLState m c a r) x@@ -294,13 +293,13 @@ {- | Construct a group and place any commands registered in the given action  into the new group. - This also resets the @help@ function back to it's original value, use+ This also resets the @help@ function back to its original value, use  'group'' if you don't want that (i.e. your help function is context aware). -} group ::     (Monad m, P.Member (P.Final m) r) =>     -- | The name of the group-    S.Text ->+    T.Text ->     P.Sem (DSLState m c a r) x ->     P.Sem (DSLState m c a r) x group name m = groupA name [] m@@ -311,35 +310,35 @@  The parent group, visibility, checks, and command help are drawn from the  reader context. - This also resets the @help@ function back to it's original value, use+ This also resets the @help@ function back to its original value, use  'group'' if you don't want that (i.e. your help function is context aware). -} groupA ::     forall x c m a r.     (Monad m, P.Member (P.Final m) r) =>     -- | The name of the group-    S.Text ->+    T.Text ->     -- | The aliases of the group-    [S.Text] ->+    [T.Text] ->     P.Sem (DSLState m c a r) x ->     P.Sem (DSLState m c a r) x groupA name aliases m = mdo     parent <- P.ask @(Maybe (Group m c a))     hidden <- P.tag $ P.ask @Bool     checks <- P.ask @[Check m c]-    help' <- P.ask @(c -> L.Text)+    help' <- P.ask @(c -> T.Text)     origHelp <- fetchOrigHelp     let group' = Group (name :| aliases) parent hidden commands children help' checks     (children, (commands, res)) <--        llisten @(LH.HashMap S.Text (Group m c a, AliasType)) $-            llisten @(LH.HashMap S.Text (Command m c a, AliasType)) $+        llisten @(LH.HashMap T.Text (Group m c a, AliasType)) $+            llisten @(LH.HashMap T.Text (Command m c a, AliasType)) $                 P.local @(Maybe (Group m c a)) (const $ Just group') $-                    P.local @(c -> L.Text) (const origHelp) m+                    P.local @(c -> T.Text) (const origHelp) m     ltell $ LH.singleton name (group', Original)     ltell $ LH.fromList [(name, (group', Alias)) | name <- aliases]     pure res -fetchOrigHelp :: P.Member (P.Tagged "original-help" (P.Reader (c -> L.Text))) r => P.Sem r (c -> L.Text)+fetchOrigHelp :: P.Member (P.Tagged "original-help" (P.Reader (c -> T.Text))) r => P.Sem r (c -> T.Text) fetchOrigHelp = P.tag P.ask  {- | Construct a group and place any commands registered in the given action@@ -348,13 +347,13 @@  The parent group, visibility, checks, and command help are drawn from the  reader context. - Unlike 'help' this doesn't reset the @help@ function back to it's original+ Unlike 'help' this doesn't reset the @help@ function back to its original  value. -} group' ::     P.Member (P.Final m) r =>     -- | The name of the group-    S.Text ->+    T.Text ->     P.Sem (DSLState m c a r) x ->     P.Sem (DSLState m c a r) x group' name m = groupA' name [] m@@ -365,27 +364,27 @@  The parent group, visibility, checks, and command help are drawn from the  reader context. - Unlike 'help' this doesn't reset the @help@ function back to it's original+ Unlike 'help' this doesn't reset the @help@ function back to its original  value. -} groupA' ::     forall x c m a r.     P.Member (P.Final m) r =>     -- | The name of the group-    S.Text ->+    T.Text ->     -- | The aliases of the group-    [S.Text] ->+    [T.Text] ->     P.Sem (DSLState m c a r) x ->     P.Sem (DSLState m c a r) x groupA' name aliases m = mdo     parent <- P.ask @(Maybe (Group m c a))     hidden <- P.tag $ P.ask @Bool     checks <- P.ask @[Check m c]-    help' <- P.ask @(c -> L.Text)+    help' <- P.ask @(c -> T.Text)     let group' = Group (name :| aliases) parent hidden commands children help' checks     (children, (commands, res)) <--        llisten @(LH.HashMap S.Text (Group m c a, AliasType)) $-            llisten @(LH.HashMap S.Text (Command m c a, AliasType)) $+        llisten @(LH.HashMap T.Text (Group m c a, AliasType)) $+            llisten @(LH.HashMap T.Text (Command m c a, AliasType)) $                 P.local @(Maybe (Group m c a)) (const $ Just group') m     ltell $ LH.singleton name (group', Original)     ltell $ LH.fromList [(name, (group', Alias)) | name <- aliases]
CalamityCommands/Error.hs view
@@ -1,21 +1,28 @@ -- | Command errors-module CalamityCommands.Error-    ( CommandError(..) ) where+module CalamityCommands.Error (CommandError (..)) where -import qualified Data.Text        as S-import qualified Data.Text.Lazy   as L+import qualified Data.Text as T -import           GHC.Generics+import GHC.Generics -import           TextShow+import TextShow import qualified TextShow.Generic as TSG  data CommandError-  = ParseError S.Text -- ^ The type of the parser-               L.Text -- ^ The reason that parsing failed-  | CheckError S.Text -- ^ The name of the check that failed-               L.Text -- ^ The reason for the check failing-  | InvokeError S.Text -- ^ The name of the command that failed-                L.Text -- ^ The reason for failing-  deriving ( Show, Generic )-  deriving ( TextShow ) via TSG.FromGeneric CommandError+    = ParseError+        T.Text+        -- ^ The type of the parser+        T.Text+        -- ^ The reason that parsing failed+    | CheckError+        T.Text+        -- ^ The name of the check that failed+        T.Text+        -- ^ The reason for the check failing+    | InvokeError+        T.Text+        -- ^ The name of the command that failed+        T.Text+        -- ^ The reason for failing+    deriving (Show, Generic)+    deriving (TextShow) via TSG.FromGeneric CommandError
CalamityCommands/Group.hs view
@@ -10,8 +10,7 @@ import Control.Lens hiding (Context, (<.>))  import qualified Data.HashMap.Lazy as LH-import qualified Data.Text as S-import qualified Data.Text.Lazy as L+import qualified Data.Text as T  import GHC.Generics @@ -22,25 +21,25 @@  -- | A group of commands data Group m c a = Group-    { names :: NonEmpty S.Text+    { names :: NonEmpty T.Text     , parent :: Maybe (Group m c a)     , hidden :: Bool     , -- | Any child commands of this group-      commands :: LH.HashMap S.Text (Command m c a, AliasType)+      commands :: LH.HashMap T.Text (Command m c a, AliasType)     , -- | Any child groups of this group-      children :: LH.HashMap S.Text (Group m c a, AliasType)+      children :: LH.HashMap T.Text (Group m c a, AliasType)     , -- | A function producing the \'help\' for the group-      help :: c -> L.Text+      help :: c -> T.Text     , -- | A list of checks that must pass       checks :: [Check m c]     }     deriving (Generic)  data GroupS m c a = GroupS-    { names :: NonEmpty S.Text-    , parent :: Maybe S.Text-    , commands :: [(S.Text, (Command m c a, AliasType))]-    , children :: [(S.Text, (Group m c a, AliasType))]+    { names :: NonEmpty T.Text+    , parent :: Maybe T.Text+    , commands :: [(T.Text, (Command m c a, AliasType))]+    , children :: [(T.Text, (Group m c a, AliasType))]     , hidden :: Bool     }     deriving (Generic, Show)
CalamityCommands/Help.hs view
@@ -22,8 +22,7 @@ import Data.List.NonEmpty (NonEmpty (..)) import qualified Data.List.NonEmpty as NE import Data.Maybe (mapMaybe)-import qualified Data.Text as S-import qualified Data.Text.Lazy as L+import qualified Data.Text as T  import qualified Polysemy as P import qualified Polysemy.Fail as P@@ -31,18 +30,20 @@  data CommandOrGroup m c a   = Command' (Command m c a)-  | Group' (Group m c a) [S.Text]+  | Group' (Group m c a) [T.Text] -parameterTypeHelp :: [ParameterInfo] -> L.Text+parameterTypeHelp :: [ParameterInfo] -> T.Text parameterTypeHelp pinfo =   let dedup = LH.toList . LH.fromList $ map (\(ParameterInfo _ t d) -> (t, d)) pinfo-      typeDescs = L.unlines ["- " <> L.pack (show t) <> ": " <> L.fromStrict d | (t, d) <- dedup]-  in "Types:\n" <> typeDescs <> "\n"+      typeDescs = T.unlines ["- " <> T.pack (show t) <> ": " <> d | (t, d) <- dedup]+  in if null dedup+      then ""+      else "Types:\n" <> typeDescs <> "\n" -helpCommandHelp :: c -> L.Text+helpCommandHelp :: c -> T.Text helpCommandHelp _ = "Show help for a command or group." -helpForCommand :: CommandContext m c a => c -> Command m c a -> L.Text+helpForCommand :: CommandContext m c a => c -> Command m c a -> T.Text helpForCommand ctx cmd@Command{names, checks, help, params} =   "Usage: " <> prefix' <> path' <> " " <> params' <> "\n"     <> aliasesFmt@@ -51,28 +52,28 @@     <> help ctx  where   prefix' = ctxPrefix ctx-  path' = L.unwords . map L.fromStrict $ commandPath cmd+  path' = T.unwords $ commandPath cmd   params' = commandParams cmd-  aliases = map L.fromStrict $ NE.tail names-  checks' = map (L.fromStrict . (^. #name)) checks+  aliases = NE.tail names+  checks' = map (^. #name) checks   aliasesFmt =     if null aliases       then ""-      else "Aliases: " <> L.unwords aliases <> "\n"+      else "Aliases: " <> T.unwords aliases <> "\n"   checksFmt =     if null checks'       then ""-      else "Checks: " <> L.unwords checks' <> "\n\n"+      else "Checks: " <> T.unwords checks' <> "\n\n" -fmtCommandWithParams :: Command m c a -> L.Text+fmtCommandWithParams :: Command m c a -> T.Text fmtCommandWithParams cmd@Command{names} = formatWithAliases names <> " " <> commandParams cmd -formatWithAliases :: NonEmpty S.Text -> L.Text-formatWithAliases (name :| aliases) = L.fromStrict name <> aliasesFmt+formatWithAliases :: NonEmpty T.Text -> T.Text+formatWithAliases (name :| aliases) = name <> aliasesFmt  where   aliasesFmt = case aliases of     [] -> ""-    aliases' -> "[" <> L.intercalate "|" (map L.fromStrict aliases') <> "]"+    aliases' -> "[" <> T.intercalate "|" aliases' <> "]"  onlyOriginals :: [(a, AliasType)] -> [a] onlyOriginals = mapMaybe inner@@ -86,7 +87,7 @@ onlyVisibleG :: [Group m c a] -> [Group m c a] onlyVisibleG = mapMaybe notHiddenG -helpForGroup :: CommandContext m c a => c -> Group m c a -> L.Text+helpForGroup :: CommandContext m c a => c -> Group m c a -> T.Text helpForGroup ctx grp =   "Group: " <> path' <> "\n"     <> aliasesFmt@@ -96,30 +97,30 @@     <> groupsMsg     <> commandsMsg  where-  path' = L.fromStrict . S.unwords $ groupPath grp+  path' = T.unwords $ groupPath grp   groups = onlyVisibleG . onlyOriginals . LH.elems $ grp ^. #children   commands = onlyVisibleC . onlyOriginals . LH.elems $ grp ^. #commands   groupsFmt = map formatWithAliases (groups ^.. traverse . #names)   groupsMsg =     if null groups       then ""-      else "The following child groups exist:\n" <> (L.unlines . map ("- " <>) $ groupsFmt)+      else "The following child groups exist:\n" <> (T.unlines . map ("- " <>) $ groupsFmt)   commandsMsg =     if null commands       then ""-      else "\nThe following child commands exist:\n" <> (L.unlines . map (("- " <>) . fmtCommandWithParams) $ commands)-  aliases = map L.fromStrict . NE.tail $ grp ^. #names-  checks' = map (L.fromStrict . (^. #name)) $ grp ^. #checks+      else "\nThe following child commands exist:\n" <> (T.unlines . map (("- " <>) . fmtCommandWithParams) $ commands)+  aliases = NE.tail $ grp ^. #names+  checks' = map (^. #name) $ grp ^. #checks   aliasesFmt =     if null aliases       then ""-      else "Aliases: " <> L.unwords aliases <> "\n"+      else "Aliases: " <> T.unwords aliases <> "\n"   checksFmt =     if null checks'       then ""-      else "Checks: " <> L.unwords checks' <> "\n\n"+      else "Checks: " <> T.unwords checks' <> "\n\n" -rootHelp :: CommandHandler m c a -> L.Text+rootHelp :: CommandHandler m c a -> T.Text rootHelp handler = groupsMsg <> commandsMsg  where   groups = onlyVisibleG . onlyOriginals . LH.elems $ handler ^. #groups@@ -128,28 +129,28 @@   groupsMsg =     if null groups       then ""-      else "The following groups exist:\n" <> (L.unlines . map ("- " <>) $ groupsFmt)+      else "The following groups exist:\n" <> (T.unlines . map ("- " <>) $ groupsFmt)   commandsMsg =     if null commands       then ""-      else "\nThe following commands exist:\n" <> (L.unlines . map (("- " <>) . fmtCommandWithParams) $ commands)+      else "\nThe following commands exist:\n" <> (T.unlines . map (("- " <>) . fmtCommandWithParams) $ commands) -renderHelp :: CommandContext m c a => CommandHandler m c a -> c -> [S.Text] -> L.Text+renderHelp :: CommandContext m c a => CommandHandler m c a -> c -> [T.Text] -> T.Text renderHelp handler ctx path =   case findCommandOrGroup handler path of     Just (Command' cmd@Command{names}) ->-      "Help for command `" <> L.fromStrict (NE.head names) <> "`: \n" <> helpForCommand ctx cmd+      "Help for command `" <> NE.head names <> "`: \n" <> helpForCommand ctx cmd     Just (Group' grp@Group{names} remainingPath) ->       let failedMsg =             if null remainingPath               then ""-              else "No command or group with the path: `" <> L.fromStrict (S.unwords remainingPath) <> "` exists for the group: `" <> L.fromStrict (NE.head names) <> "`\n"-       in failedMsg <> "Help for group `" <> L.fromStrict (NE.head names) <> "`: \n" <> helpForGroup ctx grp+              else "No command or group with the path: `" <> T.unwords remainingPath <> "` exists for the group: `" <> NE.head names <> "`\n"+       in failedMsg <> "Help for group `" <> NE.head names <> "`: \n" <> helpForGroup ctx grp     Nothing ->       let failedMsg =             if null path               then ""-              else "No command or group with the path: `" <> L.fromStrict (S.unwords path) <> "` was found.\n"+              else "No command or group with the path: `" <> T.unwords path <> "` was found.\n"        in failedMsg <> rootHelp handler  {- | Given a 'CommandHandler', optionally a parent 'Group', and a list of 'Check's,@@ -161,10 +162,10 @@   CommandHandler m c a ->   Maybe (Group m c a) ->   [Check m c] ->-  (c -> L.Text -> P.Sem (P.Fail ': r) a) ->+  (c -> T.Text -> P.Sem (P.Fail ': r) a) ->   P.Sem r (Command m c a) helpCommand' handler parent checks render =-  buildCommand @'[[S.Text]]+  buildCommand @'[[T.Text]]     ("help" :| [])     parent     False@@ -223,7 +224,7 @@ helpCommand ::   forall c m a r.   (Monad m, P.Member (P.Final m) r, CommandContext m c a) =>-  (c -> L.Text -> P.Sem (P.Fail ': r) a) ->+  (c -> T.Text -> P.Sem (P.Fail ': r) a) ->   P.Sem (DSLState m c a r) (Command m c a) helpCommand render = do   handler <- P.ask @(CommandHandler m c a)@@ -239,12 +240,12 @@ notHiddenG :: Group m c a -> Maybe (Group m c a) notHiddenG g@Group{hidden} = if hidden then Nothing else Just g -findCommandOrGroup :: CommandHandler m c a -> [S.Text] -> Maybe (CommandOrGroup m c a)+findCommandOrGroup :: CommandHandler m c a -> [T.Text] -> Maybe (CommandOrGroup m c a) findCommandOrGroup handler path = go (handler ^. #commands, handler ^. #groups) path  where   go ::-    (LH.HashMap S.Text (Command m c a, AliasType), LH.HashMap S.Text (Group m c a, AliasType)) ->-    [S.Text] ->+    (LH.HashMap T.Text (Command m c a, AliasType), LH.HashMap T.Text (Group m c a, AliasType)) ->+    [T.Text] ->     Maybe (CommandOrGroup m c a)   go (commands, groups) (x : xs) =     case LH.lookup x commands of
CalamityCommands/ParsePrefix.hs view
@@ -1,23 +1,27 @@ {-# LANGUAGE TemplateHaskell #-}  -- | Command prefix parsing effect-module CalamityCommands.ParsePrefix-    ( ParsePrefix(..)-    , parsePrefix-    , useConstantPrefix ) where+module CalamityCommands.ParsePrefix (+  ParsePrefix (..),+  parsePrefix,+  useConstantPrefix,+) where -import qualified Data.Text.Lazy                       as L+import qualified Data.Text as T -import qualified Polysemy                             as P+import qualified Polysemy as P  -- | An effect for parsing the prefix of a command. data ParsePrefix msg m a where   -- | Parse a prefix in a message, returning a tuple of @(prefix, remaining message)@-  ParsePrefix :: msg -> ParsePrefix msg m (Maybe (L.Text, L.Text))+  ParsePrefix :: msg -> ParsePrefix msg m (Maybe (T.Text, T.Text))  P.makeSem ''ParsePrefix  -- | A default interpretation for 'ParsePrefix' that uses a single constant prefix.-useConstantPrefix :: L.Text -> P.Sem (ParsePrefix L.Text ': r) a -> P.Sem r a-useConstantPrefix pre = P.interpret (\case-                                        ParsePrefix msg -> pure ((pre, ) <$> L.stripPrefix pre msg))+useConstantPrefix :: T.Text -> P.Sem (ParsePrefix T.Text ': r) a -> P.Sem r a+useConstantPrefix pre =+  P.interpret+    ( \case+        ParsePrefix msg -> pure ((pre,) <$> T.stripPrefix pre msg)+    )
CalamityCommands/Parser.hs view
@@ -24,7 +24,7 @@ import Data.List.NonEmpty (NonEmpty (..)) import Data.Maybe (fromMaybe) import Data.Semigroup-import qualified Data.Text as S+import qualified Data.Text as T import qualified Data.Text.Lazy as L import Data.Typeable @@ -41,7 +41,7 @@ import Text.Megaparsec.Char import Text.Megaparsec.Char.Lexer (decimal, float, signed) -data SpannedError = SpannedError L.Text !Int !Int+data SpannedError = SpannedError T.Text !Int !Int   deriving (Show, Eq, Ord)  {- | The current state of the parser, used so that the entire remaining input is@@ -55,20 +55,20 @@   { -- | The current offset, or where the next parser should start parsing at     off :: Int   , -- | The input message ot parse-    msg :: L.Text+    msg :: T.Text   }   deriving (Show, Generic)  -- | type ParserEffs c r =   ( P.State ParserState-      ': P.Error (S.Text, L.Text) -- (failing parser name, error reason)+      ': P.Error (T.Text, T.Text) -- (failing parser name, error reason)         ': P.Reader c -- the current parser state           ': r -- context   )  -- | Run a command parser, @ctx@ is the context, @t@ is the text input-runCommandParser :: c -> L.Text -> P.Sem (ParserEffs c r) a -> P.Sem r (Either (S.Text, L.Text) a)+runCommandParser :: c -> T.Text -> P.Sem (ParserEffs c r) a -> P.Sem r (Either (T.Text, T.Text) a) runCommandParser ctx t = P.runReader ctx . P.runError . P.evalState (ParserState 0 t)  {- | A typeclass for things that can be parsed as parameters to commands.@@ -86,7 +86,7 @@   default parameterInfo :: ParameterInfo   parameterInfo = ParameterInfo Nothing (typeRep $ Proxy @a) (parameterDescription @a @c @r) -  parameterDescription :: S.Text+  parameterDescription :: T.Text    parse :: P.Sem (ParserEffs c r) (ParserResult a) @@ -100,16 +100,16 @@    parameterInfo =     let ParameterInfo _ type_ typeDescription = parameterInfo @a @c @r-     in ParameterInfo (Just . S.pack . symbolVal $ Proxy @s) type_ typeDescription+     in ParameterInfo (Just . T.pack . symbolVal $ Proxy @s) type_ typeDescription    parameterDescription = parameterDescription @a @c @r    parse = mapE (_1 .~ parserName @(Named s a) @c @r) $ parse @a @c @r -parserName :: forall a c r. ParameterParser a c r => S.Text+parserName :: forall a c r. ParameterParser a c r => T.Text parserName =   let ParameterInfo (fromMaybe "" -> name) type_ _ = parameterInfo @a @c @r-   in name <> ":" <> S.pack (show type_)+   in name <> ":" <> T.pack (show type_)  mapE :: P.Member (P.Error e) r => (e -> e) -> P.Sem r a -> P.Sem r a mapE f m = P.catch m (P.throw . f)@@ -120,9 +120,9 @@ -} parseMP ::   -- | The name of the parser-  S.Text ->+  T.Text ->   -- | The megaparsec parser-  ParsecT SpannedError L.Text (P.Sem (P.Reader c ': r)) a ->+  ParsecT SpannedError T.Text (P.Sem (P.Reader c ': r)) a ->   P.Sem (ParserEffs c r) a parseMP n m = do   s <- P.get@@ -131,14 +131,14 @@     Right (a, offset) -> do       P.modify (#off +~ offset)       pure a-    Left s -> P.throw (n, L.pack $ errorBundlePretty s)+    Left s -> P.throw (n, T.pack $ errorBundlePretty s)  instance ParameterParser L.Text c r where-  parse = parseMP (parserName @L.Text) item+  parse = parseMP (parserName @L.Text) (L.fromStrict <$> item)   parameterDescription = "word or quoted string" -instance ParameterParser S.Text c r where-  parse = parseMP (parserName @S.Text) (L.toStrict <$> item)+instance ParameterParser T.Text c r where+  parse = parseMP (parserName @T.Text) item   parameterDescription = "word or quoted string"  instance ParameterParser Integer c r where@@ -203,7 +203,7 @@  {- | A parser that consumes zero or more of @a@ then concatenates them together. - @'KleeneStarConcat' 'L.Text'@ therefore consumes all remaining input.+ @'KleeneStarConcat' 'T.Text'@ therefore consumes all remaining input. -} data KleeneStarConcat (a :: Type) @@ -217,19 +217,19 @@   type ParserResult (KleeneStarConcat L.Text) = ParserResult L.Text    -- consume rest on text just takes everything remaining-  parse = parseMP (parserName @(KleeneStarConcat L.Text)) manySingle+  parse = parseMP (parserName @(KleeneStarConcat T.Text)) (L.fromStrict <$> manySingle)   parameterDescription = "the remaining input" -instance {-# OVERLAPS #-} ParameterParser (KleeneStarConcat S.Text) c r where-  type ParserResult (KleeneStarConcat S.Text) = ParserResult S.Text+instance {-# OVERLAPS #-} ParameterParser (KleeneStarConcat T.Text) c r where+  type ParserResult (KleeneStarConcat T.Text) = ParserResult T.Text    -- consume rest on text just takes everything remaining-  parse = parseMP (parserName @(KleeneStarConcat S.Text)) (L.toStrict <$> manySingle)+  parse = parseMP (parserName @(KleeneStarConcat T.Text)) manySingle   parameterDescription = "the remaining input"  {- | A parser that consumes one or more of @a@ then concatenates them together. - @'KleenePlusConcat' 'L.Text'@ therefore consumes all remaining input.+ @'KleenePlusConcat' 'T.Text'@ therefore consumes all remaining input. -} data KleenePlusConcat (a :: Type) @@ -243,14 +243,14 @@   type ParserResult (KleenePlusConcat L.Text) = ParserResult L.Text    -- consume rest on text just takes everything remaining-  parse = parseMP (parserName @(KleenePlusConcat L.Text)) someSingle+  parse = parseMP (parserName @(KleenePlusConcat L.Text)) (L.fromStrict <$> someSingle)   parameterDescription = "the remaining input" -instance {-# OVERLAPS #-} ParameterParser (KleenePlusConcat S.Text) c r where-  type ParserResult (KleenePlusConcat S.Text) = ParserResult S.Text+instance {-# OVERLAPS #-} ParameterParser (KleenePlusConcat T.Text) c r where+  type ParserResult (KleenePlusConcat T.Text) = ParserResult T.Text    -- consume rest on text just takes everything remaining-  parse = parseMP (parserName @(KleenePlusConcat S.Text)) (L.toStrict <$> someSingle)+  parse = parseMP (parserName @(KleenePlusConcat T.Text)) someSingle   parameterDescription = "the remaining input"  instance (ParameterParser a c r, ParameterParser b c r) => ParameterParser (a, b) c r where@@ -267,7 +267,7 @@   parameterDescription = "whitespace"  instance ShowErrorComponent SpannedError where-  showErrorComponent (SpannedError t _ _) = L.unpack t+  showErrorComponent (SpannedError t _ _) = T.unpack t   errorComponentLen (SpannedError _ s e) = max 1 $ e - s  skipN :: (Stream s, Ord e) => Int -> ParsecT e s m ()@@ -280,7 +280,7 @@   offe <- getOffset   pure (a, offe - offs) -item :: MonadParsec e L.Text m => m L.Text+item :: MonadParsec e T.Text m => m T.Text item = try quotedString <|> someNonWS  manySingle :: MonadParsec e s m => m (Tokens s)@@ -289,7 +289,7 @@ someSingle :: MonadParsec e s m => m (Tokens s) someSingle = takeWhile1P (Just "any character") (const True) -quotedString :: MonadParsec e L.Text m => m L.Text+quotedString :: MonadParsec e T.Text m => m T.Text quotedString =   try (between (chunk "'") (chunk "'") (takeWhileP (Just "any character") (/= '\'')))     <|> between (chunk "\"") (chunk "\"") (takeWhileP (Just "any character") (/= '"'))
CalamityCommands/Utils.hs view
@@ -25,8 +25,7 @@  import Data.Char (isSpace) import qualified Data.HashMap.Lazy as LH-import qualified Data.Text as S-import qualified Data.Text.Lazy as L+import qualified Data.Text as T  import GHC.Generics (Generic) @@ -42,7 +41,7 @@  data CmdInvokeFailReason c   = NoContext-  | NotFound [L.Text]+  | NotFound [T.Text]   | CommandInvokeError c CommandError   deriving (Show, Generic) @@ -82,9 +81,9 @@   -- | The message that invoked the command   msg ->   -- | The prefix used-  L.Text ->+  T.Text ->   -- | The command string, without a prefix-  L.Text ->+  T.Text ->   P.Sem r (Either (CmdInvokeFailReason c) (c, a)) handleCommands handler msg prefix cmd = P.runError $ do   (command, unparsedParams) <- P.fromEither . mapLeft NotFound $ findCommand handler cmd@@ -108,8 +107,8 @@     P.Sem (DSLState m c a r) x ->     P.Sem       (P.Fixpoint ': r)-      ( LH.HashMap S.Text (Group m c a, AliasType)-      , (LH.HashMap S.Text (Command m c a, AliasType), x)+      ( LH.HashMap T.Text (Group m c a, AliasType)+      , (LH.HashMap T.Text (Command m c a, AliasType), x)       )   inner h =     P.runReader h@@ -120,12 +119,12 @@       . P.runReader False       . P.untag @"hidden"       . P.runReader Nothing-      . runLocalWriter @(LH.HashMap S.Text (Group m c a, AliasType))-      . runLocalWriter @(LH.HashMap S.Text (Command m c a, AliasType))+      . runLocalWriter @(LH.HashMap T.Text (Group m c a, AliasType))+      . runLocalWriter @(LH.HashMap T.Text (Command m c a, AliasType))   defaultHelp = const "This command or group has no help." -nextWord :: L.Text -> (L.Text, L.Text)-nextWord = L.break isSpace . L.stripStart+nextWord :: T.Text -> (T.Text, T.Text)+nextWord = T.break isSpace . T.stripStart  {- | Attempt to find what command was used. @@ -139,31 +138,31 @@  This function isn't greedy, if you have a group and a command at the same  level, this will find the command first and ignore the group. -}-findCommand :: forall c a m. CommandHandler m c a -> L.Text -> Either [L.Text] (Command m c a, L.Text)+findCommand :: forall c a m. CommandHandler m c a -> T.Text -> Either [T.Text] (Command m c a, T.Text) findCommand handler msg = goH $ nextWord msg  where-  goH :: (L.Text, L.Text) -> Either [L.Text] (Command m c a, L.Text)+  goH :: (T.Text, T.Text) -> Either [T.Text] (Command m c a, T.Text)   goH ("", _) = Left []   goH (x, xs) =     attachSoFar       x-      ( ((,xs) <$> attachInitial (LH.lookup (L.toStrict x) (handler ^. #commands)))-          <> (attachInitial (LH.lookup (L.toStrict x) (handler ^. #groups)) >>= goG (nextWord xs))+      ( ((,xs) <$> attachInitial (LH.lookup x (handler ^. #commands)))+          <> (attachInitial (LH.lookup x (handler ^. #groups)) >>= goG (nextWord xs))       ) -  goG :: (L.Text, L.Text) -> Group m c a -> Either [L.Text] (Command m c a, L.Text)+  goG :: (T.Text, T.Text) -> Group m c a -> Either [T.Text] (Command m c a, T.Text)   goG ("", _) _ = Left []   goG (x, xs) g =     attachSoFar       x-      ( ((,xs) <$> attachInitial (LH.lookup (L.toStrict x) (g ^. #commands)))-          <> (attachInitial (LH.lookup (L.toStrict x) (g ^. #children)) >>= goG (nextWord xs))+      ( ((,xs) <$> attachInitial (LH.lookup x (g ^. #commands)))+          <> (attachInitial (LH.lookup x (g ^. #children)) >>= goG (nextWord xs))       ) -  attachInitial :: forall a b. Maybe (a, b) -> Either [L.Text] a+  attachInitial :: forall a b. Maybe (a, b) -> Either [T.Text] a   attachInitial (Just (a, _)) = Right a   attachInitial Nothing = Left [] -  attachSoFar :: forall a. L.Text -> Either [L.Text] a -> Either [L.Text] a+  attachSoFar :: forall a. T.Text -> Either [T.Text] a -> Either [T.Text] a   attachSoFar cmd (Left xs) = Left (cmd : xs)   attachSoFar _ r = r
ChangeLog.md view
@@ -1,5 +1,9 @@ # Changelog for Calamity Commands +## 0.2.0.0+++ Remove all usages of lazy Text (except from typeclass instances)+ ## 0.1.3.0  + Fixed some parameter parser instances causing type inference to fail
README.md view
@@ -43,13 +43,11 @@ import CalamityCommands.Commands.ParsePrefix import Data.Functor.Identity import qualified Data.Text as T-import qualified Data.Text.Lazy as LT import qualified Data.Text.IO as T-import qualified Data.Text.Lazy.IO as LT  -- Make a command handler, we don't actually use the context and therefore this -- handler is generic over the context used-h' :: CommandContext Identity c (Either LT.Text Int) => CommandHandler Identity c (Either LT.Text Int)+h' :: CommandContext Identity c (Either T.Text Int) => CommandHandler Identity c (Either T.Text Int) h' = runIdentity . runFinal $ do   (h, _) <- buildCommands $ do         command @'[Int, Int] "add" $ \ctx a b -> pure $ Right (a + b)@@ -71,24 +69,24 @@ -- -- This function 'r' takes an input string such as "!add 1 2", and then looks up -- the invoked command and runs it, returning the result.-r :: LT.Text -> Maybe (Either-                       (CmdInvokeFailReason (BasicContext Identity (Either LT.Text Int)))-                       (BasicContext Identity (Either LT.Text Int), Either LT.Text Int))+r :: T.Text -> Maybe (Either+                       (CmdInvokeFailReason (BasicContext Identity (Either T.Text Int)))+                       (BasicContext Identity (Either T.Text Int), Either T.Text Int)) r = runIdentity . runFinal . embedToFinal . useBasicContext . useConstantPrefix "!" . processCommands h'  -- Then to display the result of processing the command nicely, we can use a -- something like this function, which prints the result of a command if one was -- invoked successfully, and prints the error nicely if not.-rm :: LT.Text -> IO ()+rm :: T.Text -> IO () rm s = case r s of             Just (Right (_, Right r)) ->               print r              Just (Right (_, Left h)) ->-              LT.putStrLn h+              T.putStrLn h              Just (Left (CommandInvokeError _ (ParseError t r))) ->-              LT.putStrLn ("Parsing parameter " <> LT.fromStrict t <> " failed with reason: " <> r)+              T.putStrLn ("Parsing parameter " <> t <> " failed with reason: " <> r)              _ -> pure () ```
calamity-commands.cabal view
@@ -3,11 +3,9 @@ -- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack------ hash: ec3fda8daa0c65a69c2b8cfae6a5cb025d8069ab3fe541918c0d14456fa3143b  name:           calamity-commands-version:        0.1.3.0+version:        0.2.0.0 synopsis:       A library for declaring, parsing, and invoking text-input based commands description:    Please see the README on GitHub at <https://github.com/simmsb/calamity#readme> category:       Utils@@ -18,9 +16,9 @@ copyright:      2020 Ben Simms license:        MIT license-file:   LICENSE+build-type:     Simple tested-with:     GHC == 8.10.4-build-type:     Simple extra-source-files:     README.md     ChangeLog.md@@ -112,8 +110,8 @@     , lens >=4.18 && <6     , megaparsec >=8 && <10     , polysemy >=1.5 && <2-    , polysemy-plugin ==0.3.*-    , text >=1.2 && <2+    , polysemy-plugin >=0.3 && <0.5+    , text >=1.2 && <2.1     , text-show >=3.8 && <4     , unordered-containers ==0.2.*   default-language: Haskell2010