mirror of
https://github.com/teloxide/teloxide.git
synced 2025-03-22 06:45:37 +01:00
Merge pull request #34 from teloxide/rename_rename
Proper rename functionality
This commit is contained in:
commit
3d3e3eb310
7 changed files with 140 additions and 106 deletions
|
@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- `#[command(rename = "a_name_that_is_not_a_case_name")]` doesn't work anymore
|
- `#[command(rename = "...")]` now always renames to `"..."`, to rename multiple commands using the same pattern, use `#[command(rename_rule = "snake_case")]` and the like.
|
||||||
|
|
||||||
## 0.6.3 - 2022-07-19
|
## 0.6.3 - 2022-07-19
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
command::Command, command_attr::CommandAttrs, command_enum::CommandEnum,
|
command::Command, command_enum::CommandEnum, compile_error,
|
||||||
compile_error, fields_parse::impl_parse_args, unzip::Unzip, Result,
|
fields_parse::impl_parse_args, unzip::Unzip, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
@ -9,22 +9,23 @@ use syn::DeriveInput;
|
||||||
|
|
||||||
pub(crate) fn bot_commands_impl(input: DeriveInput) -> Result<TokenStream> {
|
pub(crate) fn bot_commands_impl(input: DeriveInput) -> Result<TokenStream> {
|
||||||
let data_enum = get_enum_data(&input)?;
|
let data_enum = get_enum_data(&input)?;
|
||||||
let enum_attrs = CommandAttrs::from_attributes(&input.attrs)?;
|
let command_enum = CommandEnum::from_attributes(&input.attrs)?;
|
||||||
let command_enum = CommandEnum::try_from(enum_attrs)?;
|
|
||||||
|
|
||||||
let Unzip(var_init, var_info) = data_enum
|
let Unzip(var_init, var_info) = data_enum
|
||||||
.variants
|
.variants
|
||||||
.iter()
|
.iter()
|
||||||
.map(|variant| {
|
.map(|variant| {
|
||||||
let attrs = CommandAttrs::from_attributes(&variant.attrs)?;
|
let command = Command::new(
|
||||||
let command = Command::try_from(attrs, &variant.ident.to_string())?;
|
&variant.ident.to_string(),
|
||||||
|
&variant.attrs,
|
||||||
|
&command_enum,
|
||||||
|
)?;
|
||||||
|
|
||||||
let variant_name = &variant.ident;
|
let variant_name = &variant.ident;
|
||||||
let self_variant = quote! { Self::#variant_name };
|
let self_variant = quote! { Self::#variant_name };
|
||||||
|
|
||||||
let parser =
|
let parse =
|
||||||
command.parser.as_ref().unwrap_or(&command_enum.parser_type);
|
impl_parse_args(&variant.fields, self_variant, &command.parser);
|
||||||
let parse = impl_parse_args(&variant.fields, self_variant, parser);
|
|
||||||
|
|
||||||
Ok((parse, command))
|
Ok((parse, command))
|
||||||
})
|
})
|
||||||
|
@ -32,8 +33,8 @@ pub(crate) fn bot_commands_impl(input: DeriveInput) -> Result<TokenStream> {
|
||||||
|
|
||||||
let type_name = &input.ident;
|
let type_name = &input.ident;
|
||||||
let fn_descriptions = impl_descriptions(&var_info, &command_enum);
|
let fn_descriptions = impl_descriptions(&var_info, &command_enum);
|
||||||
let fn_parse = impl_parse(&var_info, &command_enum, &var_init);
|
let fn_parse = impl_parse(&var_info, &var_init);
|
||||||
let fn_commands = impl_commands(&var_info, &command_enum);
|
let fn_commands = impl_commands(&var_info);
|
||||||
|
|
||||||
let trait_impl = quote! {
|
let trait_impl = quote! {
|
||||||
impl teloxide::utils::command::BotCommands for #type_name {
|
impl teloxide::utils::command::BotCommands for #type_name {
|
||||||
|
@ -46,15 +47,12 @@ pub(crate) fn bot_commands_impl(input: DeriveInput) -> Result<TokenStream> {
|
||||||
Ok(trait_impl)
|
Ok(trait_impl)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn impl_commands(
|
fn impl_commands(infos: &[Command]) -> proc_macro2::TokenStream {
|
||||||
infos: &[Command],
|
|
||||||
global: &CommandEnum,
|
|
||||||
) -> proc_macro2::TokenStream {
|
|
||||||
let commands = infos
|
let commands = infos
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|command| command.description_is_enabled())
|
.filter(|command| command.description_is_enabled())
|
||||||
.map(|command| {
|
.map(|command| {
|
||||||
let c = command.get_matched_value(global);
|
let c = command.get_prefixed_command();
|
||||||
let d = command.description.as_deref().unwrap_or_default();
|
let d = command.description.as_deref().unwrap_or_default();
|
||||||
quote! { BotCommand::new(#c,#d) }
|
quote! { BotCommand::new(#c,#d) }
|
||||||
});
|
});
|
||||||
|
@ -74,10 +72,9 @@ fn impl_descriptions(
|
||||||
let command_descriptions = infos
|
let command_descriptions = infos
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|command| command.description_is_enabled())
|
.filter(|command| command.description_is_enabled())
|
||||||
.map(|c| {
|
.map(|Command { prefix, name, description, ..}| {
|
||||||
let (prefix, command) = c.get_matched_value2(global);
|
let description = description.clone().unwrap_or_default();
|
||||||
let description = c.description.clone().unwrap_or_default();
|
quote! { CommandDescription { prefix: #prefix, command: #name, description: #description } }
|
||||||
quote! { CommandDescription { prefix: #prefix, command: #command, description: #description } }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let global_description = match global.description.as_deref() {
|
let global_description = match global.description.as_deref() {
|
||||||
|
@ -100,10 +97,9 @@ fn impl_descriptions(
|
||||||
|
|
||||||
fn impl_parse(
|
fn impl_parse(
|
||||||
infos: &[Command],
|
infos: &[Command],
|
||||||
global: &CommandEnum,
|
|
||||||
variants_initialization: &[proc_macro2::TokenStream],
|
variants_initialization: &[proc_macro2::TokenStream],
|
||||||
) -> proc_macro2::TokenStream {
|
) -> proc_macro2::TokenStream {
|
||||||
let matching_values = infos.iter().map(|c| c.get_matched_value(global));
|
let matching_values = infos.iter().map(|c| c.get_prefixed_command());
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
fn parse<N>(s: &str, bot_name: N) -> Result<Self, teloxide::utils::command::ParseError>
|
fn parse<N>(s: &str, bot_name: N) -> Result<Self, teloxide::utils::command::ParseError>
|
||||||
|
|
|
@ -1,55 +1,62 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
command_attr::CommandAttrs, command_enum::CommandEnum,
|
command_attr::CommandAttrs, command_enum::CommandEnum,
|
||||||
fields_parse::ParserType, rename_rules::RenameRule, Result,
|
error::compile_error_at, fields_parse::ParserType, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct Command {
|
pub(crate) struct Command {
|
||||||
pub prefix: Option<String>,
|
/// Prefix of this command, for example "/".
|
||||||
|
pub prefix: String,
|
||||||
|
/// Description for the command.
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub parser: Option<ParserType>,
|
/// Name of the command, with all renames already applied.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
/// Parser for arguments of this command.
|
||||||
|
pub parser: ParserType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn try_from(attrs: CommandAttrs, name: &str) -> Result<Self> {
|
pub fn new(
|
||||||
|
name: &str,
|
||||||
|
attributes: &[syn::Attribute],
|
||||||
|
global_options: &CommandEnum,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let attrs = CommandAttrs::from_attributes(attributes)?;
|
||||||
let CommandAttrs {
|
let CommandAttrs {
|
||||||
prefix,
|
prefix,
|
||||||
description,
|
description,
|
||||||
rename_rule,
|
rename_rule,
|
||||||
|
rename,
|
||||||
parser,
|
parser,
|
||||||
|
// FIXME: error on/do not ignore separator
|
||||||
separator: _,
|
separator: _,
|
||||||
} = attrs;
|
} = attrs;
|
||||||
|
|
||||||
let name = rename_rule.unwrap_or(RenameRule::Identity).apply(name);
|
let name = match (rename, rename_rule) {
|
||||||
|
(Some((rename, _)), None) => rename,
|
||||||
|
(Some(_), Some((_, sp))) => {
|
||||||
|
return Err(compile_error_at(
|
||||||
|
"`rename_rule` can't be applied to `rename`-d variant",
|
||||||
|
sp,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
(None, Some((rule, _))) => rule.apply(name),
|
||||||
|
(None, None) => global_options.rename_rule.apply(name),
|
||||||
|
};
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
Ok(Self { prefix, description, parser, name })
|
Ok(Self { prefix, description, parser, name })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_matched_value(&self, global_parameters: &CommandEnum) -> String {
|
pub fn get_prefixed_command(&self) -> String {
|
||||||
let prefix = if let Some(prefix) = &self.prefix {
|
let Self { prefix, name, .. } = self;
|
||||||
prefix
|
format!("{prefix}{name}")
|
||||||
} else if let Some(prefix) = &global_parameters.prefix {
|
|
||||||
prefix
|
|
||||||
} else {
|
|
||||||
"/"
|
|
||||||
};
|
|
||||||
|
|
||||||
String::from(prefix) + &global_parameters.rename_rule.apply(&self.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_matched_value2(
|
|
||||||
&self,
|
|
||||||
global_parameters: &CommandEnum,
|
|
||||||
) -> (String, String) {
|
|
||||||
let prefix = if let Some(prefix) = &self.prefix {
|
|
||||||
prefix
|
|
||||||
} else if let Some(prefix) = &global_parameters.prefix {
|
|
||||||
prefix
|
|
||||||
} else {
|
|
||||||
"/"
|
|
||||||
};
|
|
||||||
|
|
||||||
(String::from(prefix), global_parameters.rename_rule.apply(&self.name))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn description_is_enabled(&self) -> bool {
|
pub(crate) fn description_is_enabled(&self) -> bool {
|
||||||
|
|
|
@ -9,25 +9,36 @@ use crate::{
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use syn::Attribute;
|
use syn::Attribute;
|
||||||
|
|
||||||
/// Attributes for `BotCommands` derive macro.
|
/// All attributes that can be used for `derive(BotCommands)`
|
||||||
pub(crate) struct CommandAttrs {
|
pub(crate) struct CommandAttrs {
|
||||||
pub prefix: Option<String>,
|
pub prefix: Option<(String, Span)>,
|
||||||
pub description: Option<String>,
|
pub description: Option<(String, Span)>,
|
||||||
pub rename_rule: Option<RenameRule>,
|
pub rename_rule: Option<(RenameRule, Span)>,
|
||||||
pub parser: Option<ParserType>,
|
pub rename: Option<(String, Span)>,
|
||||||
pub separator: Option<String>,
|
pub parser: Option<(ParserType, Span)>,
|
||||||
|
pub separator: Option<(String, Span)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An attribute for `BotCommands` derive macro.
|
/// A single k/v attribute for `BotCommands` derive macro.
|
||||||
pub(crate) struct CommandAttr {
|
///
|
||||||
|
/// For example:
|
||||||
|
/// ```text
|
||||||
|
/// #[command(prefix = "!", rename_rule = "snake_case")]
|
||||||
|
/// /^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^---- CommandAttr { kind: RenameRule(SnakeCase) }
|
||||||
|
/// |
|
||||||
|
/// CommandAttr { kind: Prefix("!") }
|
||||||
|
/// ```
|
||||||
|
struct CommandAttr {
|
||||||
kind: CommandAttrKind,
|
kind: CommandAttrKind,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum CommandAttrKind {
|
/// Kind of [`CommandAttr`].
|
||||||
|
enum CommandAttrKind {
|
||||||
Prefix(String),
|
Prefix(String),
|
||||||
Description(String),
|
Description(String),
|
||||||
Rename(RenameRule),
|
RenameRule(RenameRule),
|
||||||
|
Rename(String),
|
||||||
ParseWith(ParserType),
|
ParseWith(ParserType),
|
||||||
Separator(String),
|
Separator(String),
|
||||||
}
|
}
|
||||||
|
@ -44,18 +55,19 @@ impl CommandAttrs {
|
||||||
prefix: None,
|
prefix: None,
|
||||||
description: None,
|
description: None,
|
||||||
rename_rule: None,
|
rename_rule: None,
|
||||||
|
rename: None,
|
||||||
parser: None,
|
parser: None,
|
||||||
separator: None,
|
separator: None,
|
||||||
},
|
},
|
||||||
|mut this, attr| {
|
|mut this, attr| {
|
||||||
fn insert<T>(
|
fn insert<T>(
|
||||||
opt: &mut Option<T>,
|
opt: &mut Option<(T, Span)>,
|
||||||
x: T,
|
x: T,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match opt {
|
match opt {
|
||||||
slot @ None => {
|
slot @ None => {
|
||||||
*slot = Some(x);
|
*slot = Some((x, sp));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
@ -67,7 +79,8 @@ impl CommandAttrs {
|
||||||
match attr.kind {
|
match attr.kind {
|
||||||
Prefix(p) => insert(&mut this.prefix, p, attr.sp),
|
Prefix(p) => insert(&mut this.prefix, p, attr.sp),
|
||||||
Description(d) => insert(&mut this.description, d, attr.sp),
|
Description(d) => insert(&mut this.description, d, attr.sp),
|
||||||
Rename(r) => insert(&mut this.rename_rule, r, attr.sp),
|
RenameRule(r) => insert(&mut this.rename_rule, r, attr.sp),
|
||||||
|
Rename(r) => insert(&mut this.rename, r, attr.sp),
|
||||||
ParseWith(p) => insert(&mut this.parser, p, attr.sp),
|
ParseWith(p) => insert(&mut this.parser, p, attr.sp),
|
||||||
Separator(s) => insert(&mut this.separator, s, attr.sp),
|
Separator(s) => insert(&mut this.separator, s, attr.sp),
|
||||||
}?;
|
}?;
|
||||||
|
@ -87,9 +100,12 @@ impl CommandAttr {
|
||||||
let kind = match &*key.to_string() {
|
let kind = match &*key.to_string() {
|
||||||
"prefix" => Prefix(value.expect_string()?),
|
"prefix" => Prefix(value.expect_string()?),
|
||||||
"description" => Description(value.expect_string()?),
|
"description" => Description(value.expect_string()?),
|
||||||
"rename" => Rename(
|
"rename_rule" => RenameRule(
|
||||||
value.expect_string().and_then(|r| RenameRule::parse(&r))?,
|
value
|
||||||
|
.expect_string()
|
||||||
|
.and_then(|r| self::RenameRule::parse(&r))?,
|
||||||
),
|
),
|
||||||
|
"rename" => Rename(value.expect_string()?),
|
||||||
"parse_with" => {
|
"parse_with" => {
|
||||||
ParseWith(value.expect_string().map(|p| ParserType::parse(&p))?)
|
ParseWith(value.expect_string().map(|p| ParserType::parse(&p))?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,50 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
command_attr::CommandAttrs, fields_parse::ParserType,
|
command_attr::CommandAttrs, error::compile_error_at,
|
||||||
rename_rules::RenameRule, Result,
|
fields_parse::ParserType, rename_rules::RenameRule, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct CommandEnum {
|
pub(crate) struct CommandEnum {
|
||||||
pub prefix: Option<String>,
|
pub prefix: String,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub rename_rule: RenameRule,
|
pub rename_rule: RenameRule,
|
||||||
pub parser_type: ParserType,
|
pub parser_type: ParserType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandEnum {
|
impl CommandEnum {
|
||||||
pub fn try_from(attrs: CommandAttrs) -> Result<Self> {
|
pub fn from_attributes(attributes: &[syn::Attribute]) -> Result<Self> {
|
||||||
|
let attrs = CommandAttrs::from_attributes(attributes)?;
|
||||||
let CommandAttrs {
|
let CommandAttrs {
|
||||||
prefix,
|
prefix,
|
||||||
description,
|
description,
|
||||||
rename_rule,
|
rename_rule,
|
||||||
|
rename,
|
||||||
parser,
|
parser,
|
||||||
separator,
|
separator,
|
||||||
} = attrs;
|
} = attrs;
|
||||||
let mut parser = parser.unwrap_or(ParserType::Default);
|
|
||||||
|
if let Some((_rename, sp)) = rename {
|
||||||
|
return Err(compile_error_at(
|
||||||
|
"`rename` attribute can only be applied to enums *variants*",
|
||||||
|
sp,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut parser = parser.map(|(p, _)| p).unwrap_or(ParserType::Default);
|
||||||
|
|
||||||
// FIXME: Error on unused separator
|
// FIXME: Error on unused separator
|
||||||
if let (ParserType::Split { separator }, Some(s)) =
|
if let (ParserType::Split { separator }, Some((s, _))) =
|
||||||
(&mut parser, &separator)
|
(&mut parser, &separator)
|
||||||
{
|
{
|
||||||
*separator = Some(s.clone())
|
*separator = Some(s.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
prefix,
|
prefix: prefix.map(|(p, _)| p).unwrap_or_else(|| "/".to_owned()),
|
||||||
description,
|
description: description.map(|(d, _)| d),
|
||||||
rename_rule: rename_rule.unwrap_or(RenameRule::Identity),
|
rename_rule: rename_rule
|
||||||
|
.map(|(rr, _)| rr)
|
||||||
|
.unwrap_or(RenameRule::Identity),
|
||||||
parser_type: parser,
|
parser_type: parser,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{Fields, FieldsNamed, FieldsUnnamed, Type};
|
use syn::{Fields, FieldsNamed, FieldsUnnamed, Type};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum ParserType {
|
pub(crate) enum ParserType {
|
||||||
Default,
|
Default,
|
||||||
Split { separator: Option<String> },
|
Split { separator: Option<String> },
|
||||||
|
|
|
@ -9,7 +9,7 @@ use teloxide::utils::command::BotCommands as _;
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_command_with_args() {
|
fn parse_command_with_args() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
Start(String),
|
Start(String),
|
||||||
Help,
|
Help,
|
||||||
|
@ -24,7 +24,7 @@ fn parse_command_with_args() {
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_command_with_non_string_arg() {
|
fn parse_command_with_non_string_arg() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
Start(i32),
|
Start(i32),
|
||||||
Help,
|
Help,
|
||||||
|
@ -39,7 +39,7 @@ fn parse_command_with_non_string_arg() {
|
||||||
#[test]
|
#[test]
|
||||||
fn attribute_prefix() {
|
fn attribute_prefix() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
#[command(prefix = "!")]
|
#[command(prefix = "!")]
|
||||||
Start(String),
|
Start(String),
|
||||||
|
@ -55,7 +55,7 @@ fn attribute_prefix() {
|
||||||
#[test]
|
#[test]
|
||||||
fn many_attributes() {
|
fn many_attributes() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
#[command(prefix = "!", description = "desc")]
|
#[command(prefix = "!", description = "desc")]
|
||||||
Start,
|
Start,
|
||||||
|
@ -75,7 +75,11 @@ fn many_attributes() {
|
||||||
#[test]
|
#[test]
|
||||||
fn global_attributes() {
|
fn global_attributes() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(prefix = "!", rename = "lowercase", description = "Bot commands")]
|
#[command(
|
||||||
|
prefix = "!",
|
||||||
|
rename_rule = "lowercase",
|
||||||
|
description = "Bot commands"
|
||||||
|
)]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
#[command(prefix = "/")]
|
#[command(prefix = "/")]
|
||||||
Start,
|
Start,
|
||||||
|
@ -99,7 +103,7 @@ fn global_attributes() {
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_command_with_bot_name() {
|
fn parse_command_with_bot_name() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
#[command(prefix = "/")]
|
#[command(prefix = "/")]
|
||||||
Start,
|
Start,
|
||||||
|
@ -115,7 +119,7 @@ fn parse_command_with_bot_name() {
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_with_split() {
|
fn parse_with_split() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
#[command(parse_with = "split")]
|
#[command(parse_with = "split")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
Start(u8, String),
|
Start(u8, String),
|
||||||
|
@ -131,7 +135,7 @@ fn parse_with_split() {
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_with_split2() {
|
fn parse_with_split2() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
#[command(parse_with = "split", separator = "|")]
|
#[command(parse_with = "split", separator = "|")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
Start(u8, String),
|
Start(u8, String),
|
||||||
|
@ -174,7 +178,7 @@ fn parse_custom_parser() {
|
||||||
use parser::custom_parse_function;
|
use parser::custom_parse_function;
|
||||||
|
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
#[command(parse_with = "custom_parse_function")]
|
#[command(parse_with = "custom_parse_function")]
|
||||||
Start(u8, String),
|
Start(u8, String),
|
||||||
|
@ -199,7 +203,7 @@ fn parse_custom_parser() {
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_named_fields() {
|
fn parse_named_fields() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
#[command(parse_with = "split")]
|
#[command(parse_with = "split")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
Start { num: u8, data: String },
|
Start { num: u8, data: String },
|
||||||
|
@ -215,7 +219,7 @@ fn parse_named_fields() {
|
||||||
#[test]
|
#[test]
|
||||||
fn descriptions_off() {
|
fn descriptions_off() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
#[command(description = "off")]
|
#[command(description = "off")]
|
||||||
Start,
|
Start,
|
||||||
|
@ -229,24 +233,24 @@ fn descriptions_off() {
|
||||||
fn rename_rules() {
|
fn rename_rules() {
|
||||||
#[derive(BotCommands, Debug, PartialEq)]
|
#[derive(BotCommands, Debug, PartialEq)]
|
||||||
enum DefaultCommands {
|
enum DefaultCommands {
|
||||||
#[command(rename = "lowercase")]
|
#[command(rename_rule = "lowercase")]
|
||||||
AaaAaa,
|
AaaAaa,
|
||||||
#[command(rename = "UPPERCASE")]
|
#[command(rename_rule = "UPPERCASE")]
|
||||||
BbbBbb,
|
BbbBbb,
|
||||||
#[command(rename = "PascalCase")]
|
#[command(rename_rule = "PascalCase")]
|
||||||
CccCcc,
|
CccCcc,
|
||||||
#[command(rename = "camelCase")]
|
#[command(rename_rule = "camelCase")]
|
||||||
DddDdd,
|
DddDdd,
|
||||||
#[command(rename = "snake_case")]
|
#[command(rename_rule = "snake_case")]
|
||||||
EeeEee,
|
EeeEee,
|
||||||
#[command(rename = "SCREAMING_SNAKE_CASE")]
|
#[command(rename_rule = "SCREAMING_SNAKE_CASE")]
|
||||||
FffFff,
|
FffFff,
|
||||||
#[command(rename = "kebab-case")]
|
#[command(rename_rule = "kebab-case")]
|
||||||
GggGgg,
|
GggGgg,
|
||||||
#[command(rename = "SCREAMING-KEBAB-CASE")]
|
#[command(rename_rule = "SCREAMING-KEBAB-CASE")]
|
||||||
HhhHhh,
|
HhhHhh,
|
||||||
//#[command(rename = "Bar")]
|
#[command(rename = "Bar")]
|
||||||
//Foo,
|
Foo,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -281,16 +285,14 @@ fn rename_rules() {
|
||||||
DefaultCommands::HhhHhh,
|
DefaultCommands::HhhHhh,
|
||||||
DefaultCommands::parse("/HHH-HHH", "").unwrap()
|
DefaultCommands::parse("/HHH-HHH", "").unwrap()
|
||||||
);
|
);
|
||||||
//assert_eq!(DefaultCommands::Foo, DefaultCommands::parse("/Bar",
|
assert_eq!(
|
||||||
// "").unwrap());
|
DefaultCommands::Foo,
|
||||||
|
DefaultCommands::parse("/Bar", "").unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
|
||||||
// "/aaaaaa\n/BBBBBB\n/CccCcc\n/dddDdd\n/eee_eee\n/FFF_FFF\n/ggg-ggg\n/
|
|
||||||
// HHH-HHH\n/Bar", DefaultCommands::descriptions().to_string()
|
|
||||||
// );
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
"/aaaaaa\n/BBBBBB\n/CccCcc\n/dddDdd\n/eee_eee\n/FFF_FFF\n/ggg-ggg\n/\
|
"/aaaaaa\n/BBBBBB\n/CccCcc\n/dddDdd\n/eee_eee\n/FFF_FFF\n/ggg-ggg\n/\
|
||||||
HHH-HHH",
|
HHH-HHH\n/Bar",
|
||||||
DefaultCommands::descriptions().to_string()
|
DefaultCommands::descriptions().to_string()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue