Add deprecation warning for #[command(description = "off")]

This commit is contained in:
Maybe Waffle 2023-06-13 20:31:52 +04:00
parent c7c6b029b0
commit f538faa966
2 changed files with 28 additions and 7 deletions

View file

@ -4,7 +4,7 @@ use crate::{
}; };
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::{quote, quote_spanned};
use syn::DeriveInput; use syn::DeriveInput;
pub(crate) fn bot_commands_impl(input: DeriveInput) -> Result<TokenStream> { pub(crate) fn bot_commands_impl(input: DeriveInput) -> Result<TokenStream> {
@ -45,7 +45,7 @@ pub(crate) fn bot_commands_impl(input: DeriveInput) -> Result<TokenStream> {
fn impl_commands(infos: &[Command]) -> proc_macro2::TokenStream { fn impl_commands(infos: &[Command]) -> proc_macro2::TokenStream {
let commands = infos.iter().filter(|command| command.description_is_enabled()).map(|command| { let commands = infos.iter().filter(|command| command.description_is_enabled()).map(|command| {
let c = command.get_prefixed_command(); let c = command.get_prefixed_command();
let d = command.description.as_deref().unwrap_or_default(); let d = command.description().unwrap_or_default();
quote! { BotCommand::new(#c,#d) } quote! { BotCommand::new(#c,#d) }
}); });
@ -61,11 +61,21 @@ fn impl_descriptions(infos: &[Command], global: &CommandEnum) -> proc_macro2::To
let command_descriptions = infos let command_descriptions = infos
.iter() .iter()
.filter(|command| command.description_is_enabled()) .filter(|command| command.description_is_enabled())
.map(|Command { prefix, name, description, ..}| { .map(|command @ Command { prefix, name, ..}| {
let description = description.clone().unwrap_or_default(); let description = command.description().unwrap_or_default();
quote! { CommandDescription { prefix: #prefix, command: #name, description: #description } } quote! { CommandDescription { prefix: #prefix, command: #name, description: #description } }
}); });
let warnings = infos.iter().filter_map(|command| command.deprecated_description_off_span()).map(|span| {
quote_spanned! { span =>
const _: () = {
#[deprecated(note="\n`description = \"off\"` is deprecated, use `hide` instead")]
struct Deprecated;
_ = Deprecated;
};
}
});
let global_description = match global.description.as_deref() { let global_description = match global.description.as_deref() {
Some(gd) => quote! { .global_description(#gd) }, Some(gd) => quote! { .global_description(#gd) },
None => quote! {}, None => quote! {},
@ -76,6 +86,8 @@ fn impl_descriptions(infos: &[Command], global: &CommandEnum) -> proc_macro2::To
use teloxide::utils::command::{CommandDescriptions, CommandDescription}; use teloxide::utils::command::{CommandDescriptions, CommandDescription};
use std::borrow::Cow; use std::borrow::Cow;
#(#warnings)*
CommandDescriptions::new(&[ CommandDescriptions::new(&[
#(#command_descriptions),* #(#command_descriptions),*
]) ])

View file

@ -1,3 +1,5 @@
use proc_macro2::Span;
use crate::{ use crate::{
command_attr::CommandAttrs, command_enum::CommandEnum, error::compile_error_at, command_attr::CommandAttrs, command_enum::CommandEnum, error::compile_error_at,
fields_parse::ParserType, Result, fields_parse::ParserType, Result,
@ -7,7 +9,7 @@ pub(crate) struct Command {
/// Prefix of this command, for example "/". /// Prefix of this command, for example "/".
pub prefix: String, pub prefix: String,
/// Description for the command. /// Description for the command.
pub description: Option<String>, pub description: Option<(String, Span)>,
/// Name of the command, with all renames already applied. /// Name of the command, with all renames already applied.
pub name: String, pub name: String,
/// Parser for arguments of this command. /// Parser for arguments of this command.
@ -47,7 +49,6 @@ impl Command {
}; };
let prefix = prefix.map(|(p, _)| p).unwrap_or_else(|| global_options.prefix.clone()); let prefix = prefix.map(|(p, _)| p).unwrap_or_else(|| global_options.prefix.clone());
let description = description.map(|(d, _)| d);
let parser = parser.map(|(p, _)| p).unwrap_or_else(|| global_options.parser_type.clone()); let parser = parser.map(|(p, _)| p).unwrap_or_else(|| global_options.parser_type.clone());
let hidden = hide.is_some(); let hidden = hide.is_some();
@ -59,8 +60,16 @@ impl Command {
format!("{prefix}{name}") format!("{prefix}{name}")
} }
pub fn description(&self) -> Option<&str> {
self.description.as_ref().map(|(d, _span)| &**d)
}
pub(crate) fn description_is_enabled(&self) -> bool { pub(crate) fn description_is_enabled(&self) -> bool {
// FIXME: remove the first, `== "off"`, check eventually // FIXME: remove the first, `== "off"`, check eventually
self.description != Some("off".to_owned()) && !self.hidden self.description() != Some("off") && !self.hidden
}
pub(crate) fn deprecated_description_off_span(&self) -> Option<Span> {
self.description.as_ref().filter(|(d, _)| d == "off").map(|&(_, span)| span)
} }
} }