diff --git a/crates/teloxide-macros/src/command.rs b/crates/teloxide-macros/src/command.rs index fb421e8f..a10e0a50 100644 --- a/crates/teloxide-macros/src/command.rs +++ b/crates/teloxide-macros/src/command.rs @@ -12,6 +12,8 @@ pub(crate) struct Command { pub name: String, /// Parser for arguments of this command. pub parser: ParserType, + /// Whether the command is hidden from the help message. + pub hidden: bool, } impl Command { @@ -29,6 +31,7 @@ impl Command { parser, // FIXME: error on/do not ignore separator separator: _, + hide, } = attrs; let name = match (rename, rename_rule) { @@ -47,7 +50,7 @@ impl Command { let description = description.map(|(d, _)| d); let parser = parser.map(|(p, _)| p).unwrap_or_else(|| global_options.parser_type.clone()); - Ok(Self { prefix, description, parser, name }) + Ok(Self { prefix, description, parser, name, hidden: hide.is_some() }) } pub fn get_prefixed_command(&self) -> String { @@ -56,6 +59,6 @@ impl Command { } pub(crate) fn description_is_enabled(&self) -> bool { - self.description != Some("off".to_owned()) + self.description != Some("off".to_owned()) && !self.hidden } } diff --git a/crates/teloxide-macros/src/command_attr.rs b/crates/teloxide-macros/src/command_attr.rs index 96c9c2b7..5c916a7b 100644 --- a/crates/teloxide-macros/src/command_attr.rs +++ b/crates/teloxide-macros/src/command_attr.rs @@ -17,6 +17,7 @@ pub(crate) struct CommandAttrs { pub rename: Option<(String, Span)>, pub parser: Option<(ParserType, Span)>, pub separator: Option<(String, Span)>, + pub hide: Option<((), Span)>, } /// A single k/v attribute for `BotCommands` derive macro. @@ -41,6 +42,7 @@ enum CommandAttrKind { Rename(String), ParseWith(ParserType), Separator(String), + Hide, } impl CommandAttrs { @@ -58,6 +60,7 @@ impl CommandAttrs { rename: None, parser: None, separator: None, + hide: None, }, |mut this, attr| { fn insert(opt: &mut Option<(T, Span)>, x: T, sp: Span) -> Result<()> { @@ -77,6 +80,7 @@ impl CommandAttrs { Rename(r) => insert(&mut this.rename, r, attr.sp), ParseWith(p) => insert(&mut this.parser, p, attr.sp), Separator(s) => insert(&mut this.separator, s, attr.sp), + Hide => insert(&mut this.hide, (), attr.sp), }?; Ok(this) @@ -100,10 +104,11 @@ impl CommandAttr { "rename" => Rename(value.expect_string()?), "parse_with" => ParseWith(ParserType::parse(value)?), "separator" => Separator(value.expect_string()?), + "hide" => Hide, _ => { return Err(compile_error_at( "unexpected attribute name (expected one of `prefix`, `description`, \ - `rename`, `parse_with` and `separator`", + `rename`, `parse_with`, `separator` and `hide`", key.span(), )) } diff --git a/crates/teloxide-macros/src/command_enum.rs b/crates/teloxide-macros/src/command_enum.rs index 83f20dec..3648d3ae 100644 --- a/crates/teloxide-macros/src/command_enum.rs +++ b/crates/teloxide-macros/src/command_enum.rs @@ -13,13 +13,19 @@ pub(crate) struct CommandEnum { impl CommandEnum { pub fn from_attributes(attributes: &[syn::Attribute]) -> Result { let attrs = CommandAttrs::from_attributes(attributes)?; - let CommandAttrs { prefix, description, rename_rule, rename, parser, separator } = attrs; + let CommandAttrs { prefix, description, rename_rule, rename, parser, separator, hide } = + attrs; if let Some((_rename, sp)) = rename { return Err(compile_error_at( "`rename` attribute can only be applied to enums *variants*", sp, )); + } else if let Some((_hide, sp)) = hide { + return Err(compile_error_at( + "`hide` attribute can only be applied to enums *variants*", + sp, + )); } let mut parser = parser.map(|(p, _)| p).unwrap_or(ParserType::Default);