Command syntax, esp. optional arguments
In https://github.com/8573/irc-bot.rs/issues/50#issuecomment-514828190, @ctm wrote—
I've only been playing with irc-bot for about a day. I've found it easy to use, although I haven't yet figured out how to make a command that takes an optional argument. In specific, I'd like to be able to support
bet,bet N(where N is a positive number),bet potandbet half, but, at least when using the source from thedevbranch of this repository, I get:
Error: While handling YAML: Expected <argument> to be of type Scalar, but it is of type Mapping.for just
bet, althoughbet ""works fine. I'm using"<amount>"as the argument to thesyntaxparameter ofModuleBuilder::command. I tried"...", but that fails to compile. With"<amount>", the zero-length string as input is converted to an empty Hash which is whyyaml::check_typedies. I'm early enough into development that this doesn't really matter to me, and I realize there may be some other argument tosyntaxthat might work.
Sorry about this! The API for defining commands, especially around taking arguments, is one of the older and messier ones, if not the messiest, and is so poorly documented that I can't even find any generated list of items for it in the documentation. (I suppose its "documentation" consists of the examples provided by the bot modules in src/modules.) Now that I have users other than myself, I realize that it well may be overly restrictive that the "commands" must take YAML objects as arguments, if they take any argument.
The way to have an optional argument like this with a command per se would be to make the argument a YAML mapping (what yaml-rust calls a Hash) and have the optional arguments be optional fields of that mapping, leading to an interface such as—
pokerbot: bet
pokerbot: bet amt: <N>
pokerbot: bet type: pot
pokerbot: bet type: half
However, it currently should be possible to get the interface you intended by using not commands per se but rather the similar feature currently named "triggers", which allow matching incoming messages against an arbitrary regex and running a given function for matching messages, with the regex's captures passed to the function. For your case, I imagine the regex would be ^bet(?: ([0-9]+|pot|half))?$.
These APIs deserve to be overhauled, and I imagine I might unify them into a single, more flexible API. Whether or not I do, I intend to rename triggers to something else, because, if eventually I write documentation for them, I otherwise would be talking about triggers being triggered and what triggers triggers, which could get confusing.
Thank you very much for the quick response!
I did see that I could do a YAML mapping, but I didn't want my users to have to supply the key. We're old farts with muscle memory going back to the goodle days and we're happy to have any memory at all.
I did briefly see how triggers worked, but because of the name, I didn't think of them, especially since commands were so close to what I wanted to do that I fixated on them.