Parse path instead of string when parsing parse_with

This commit is contained in:
Maybe Waffle 2022-10-06 14:18:29 +04:00
parent 3d3e3eb310
commit ff1e0fc305
5 changed files with 19 additions and 20 deletions

View file

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- `#[command(rename = "...")]` now always renames to `"..."`, to rename multiple commands using the same pattern, use `#[command(rename_rule = "snake_case")]` and the like.
- `#[command(parse_with = ...)]` now requires a path, instead of a string, when specifying custom parsers
## 0.6.3 - 2022-07-19

View file

@ -99,7 +99,7 @@ impl AttrValue {
// })
// }
fn expect<T>(
pub fn expect<T>(
self,
expected: &str,
f: impl FnOnce(Self) -> Result<T, Self>,

View file

@ -106,9 +106,7 @@ impl CommandAttr {
.and_then(|r| self::RenameRule::parse(&r))?,
),
"rename" => Rename(value.expect_string()?),
"parse_with" => {
ParseWith(value.expect_string().map(|p| ParserType::parse(&p))?)
}
"parse_with" => ParseWith(ParserType::parse(value)?),
"separator" => Separator(value.expect_string()?),
_ => {
return Err(compile_error_at(

View file

@ -1,21 +1,26 @@
use quote::quote;
use syn::{Fields, FieldsNamed, FieldsUnnamed, Type};
use crate::{attr::AttrValue, error::Result};
#[derive(Debug, Clone)]
pub(crate) enum ParserType {
Default,
Split { separator: Option<String> },
Custom(String),
Custom(syn::Path),
}
impl ParserType {
// FIXME: use path for custom
pub fn parse(data: &str) -> Self {
match data {
"default" => ParserType::Default,
"split" => ParserType::Split { separator: None },
s => ParserType::Custom(s.to_owned()),
}
pub fn parse(value: AttrValue) -> Result<Self> {
value.expect(r#""default", "split" or a path"#, |v| match v {
AttrValue::Path(p) => Ok(ParserType::Custom(p)),
AttrValue::Lit(syn::Lit::Str(ref l)) => match &*l.value() {
"default" => Ok(ParserType::Default),
"split" => Ok(ParserType::Split { separator: None }),
_ => Err(v),
},
_ => Err(v),
})
}
}
@ -101,12 +106,7 @@ fn create_parser<'a>(
&separator.clone().unwrap_or_else(|| " ".to_owned()),
types,
),
ParserType::Custom(s) => {
let path = syn::parse_str::<syn::Path>(s).unwrap_or_else(|_| {
panic!("Failed to parse a custom command parser, {}", s)
});
quote! { #path }
}
ParserType::Custom(path) => quote! { #path },
};
quote! {

View file

@ -180,11 +180,11 @@ fn parse_custom_parser() {
#[derive(BotCommands, Debug, PartialEq)]
#[command(rename_rule = "lowercase")]
enum DefaultCommands {
#[command(parse_with = "custom_parse_function")]
#[command(parse_with = custom_parse_function)]
Start(u8, String),
// Test <https://github.com/teloxide/teloxide/issues/668>.
#[command(parse_with = "parser::custom_parse_function")]
#[command(parse_with = parser::custom_parse_function)]
TestPath(u8, String),
Help,