Merge pull request #36 from teloxide/parse_with_use_path

Parse path instead of string when parsing `parse_with`
This commit is contained in:
Waffle Maybe 2022-10-06 15:28:45 +04:00 committed by GitHub
commit 6c026dde7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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 ### 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(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 ## 0.6.3 - 2022-07-19

View file

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

View file

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

View file

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

View file

@ -180,11 +180,11 @@ fn parse_custom_parser() {
#[derive(BotCommands, Debug, PartialEq)] #[derive(BotCommands, Debug, PartialEq)]
#[command(rename_rule = "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),
// Test <https://github.com/teloxide/teloxide/issues/668>. // 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), TestPath(u8, String),
Help, Help,