From a918eb4e507f8a4d83f6151a17db2c982339ab5b Mon Sep 17 00:00:00 2001 From: p0lunin Date: Mon, 1 Jun 2020 22:33:51 +0300 Subject: [PATCH] refactoring + fmt --- src/command.rs | 2 +- src/{enum_attributes.rs => command_enum.rs} | 0 src/fields_parse.rs | 42 +++++++++++++-------- src/lib.rs | 12 +++--- 4 files changed, 33 insertions(+), 23 deletions(-) rename src/{enum_attributes.rs => command_enum.rs} (100%) diff --git a/src/command.rs b/src/command.rs index fd201f4f..8a5f3a3a 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,4 +1,4 @@ -use crate::enum_attributes::CommandEnum; +use crate::command_enum::CommandEnum; use crate::fields_parse::ParserType; use crate::{ attr::{Attr, BotCommandAttribute}, diff --git a/src/enum_attributes.rs b/src/command_enum.rs similarity index 100% rename from src/enum_attributes.rs rename to src/command_enum.rs diff --git a/src/fields_parse.rs b/src/fields_parse.rs index e06f421a..3b38c38f 100644 --- a/src/fields_parse.rs +++ b/src/fields_parse.rs @@ -2,7 +2,7 @@ extern crate quote; use quote::__private::Span; use quote::{quote, ToTokens}; -use syn::{FieldsUnnamed, FieldsNamed}; +use syn::{FieldsNamed, FieldsUnnamed}; #[derive(Debug)] pub enum ParserType { @@ -58,41 +58,51 @@ pub fn impl_parse_args_named( res } - fn create_parser(parser_type: &ParserType, count_args: usize) -> quote::__private::TokenStream { let function_to_parse = match parser_type { - ParserType::Default => { - match count_args { - 1 => { - quote! { (|s: String| Ok((FromStr::from_str(&s).map_err(|_|ParseError::UncorrectFormat)?,)) ) } - } - _ => quote! { compile_error!("Expected 1 argument") }, + ParserType::Default => match count_args { + 1 => { + quote! { (|s: String| Ok((FromStr::from_str(&s).map_err(|_|ParseError::IncorrectFormat)?,)) ) } } + _ => quote! { compile_error!("Expected 1 argument") }, + }, + ParserType::Split { separator } => { + parser_with_separator(&separator.clone().unwrap_or(" ".to_owned()), count_args) } - ParserType::Split { separator } => parser_with_separator( - &separator.clone().unwrap_or(" ".to_owned()), - count_args, - ), ParserType::Custom(s) => { let ident = syn::Ident::new(&s, Span::call_site()); quote! { #ident } } }; - quote! { let arguments = #function_to_parse(args)?; } + quote! { + let arguments = #function_to_parse(args)?; + } } fn parser_with_separator(separator: &str, count_args: usize) -> quote::__private::TokenStream { - let inner = quote! { let splited = s.split(#separator).collect::>(); }; + let inner = quote! { let mut splited = s.split(#separator); }; let mut inner2 = quote! {}; for i in 0..count_args { inner2.extend( - quote! { FromStr::from_str(splited[#i]).map_err(|_|ParseError::UncorrectFormat)?, }, + quote! { FromStr::from_str(splited.next().ok_or(ParseError::TooFewArguments { + expected: #count_args, + found: #i, + message: format!("Expected but not found arg number {}", #i + 1), + })?).map_err(|_|ParseError::IncorrectFormat)?, }, ) } let res = quote! { (|s: String| { #inner - Ok((#inner2)) + let res = (#inner2); + match splited.next() { + Some(d) => Err(ParseError::TooManyArguments { + expected: #count_args, + found: #count_args + 1, + message: format!("Excess argument: {}", d), + }), + None => Ok(res) + } }) }; res diff --git a/src/lib.rs b/src/lib.rs index aba3f73b..ad083f9b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,17 @@ mod attr; mod command; -mod enum_attributes; +mod command_enum; mod fields_parse; mod rename_rules; extern crate proc_macro; extern crate quote; extern crate syn; -use crate::fields_parse::{impl_parse_args_unnamed, impl_parse_args_named}; +use crate::fields_parse::{impl_parse_args_named, impl_parse_args_unnamed}; use crate::{ attr::{Attr, VecAttrs}, command::Command, - enum_attributes::CommandEnum, + command_enum::CommandEnum, }; use proc_macro::TokenStream; use quote::{quote, ToTokens}; @@ -129,8 +129,8 @@ fn impl_parse( { use std::str::FromStr; let mut words = s.splitn(2, ' '); - let mut splited = words.next().ok_or(ParseError::UncorrectFormat)?.split('@'); - let command_raw = splited.next().ok_or(ParseError::UncorrectFormat)?; + let mut splited = words.next().expect("First item will be always.").split('@'); + let command_raw = splited.next().expect("First item will be always."); let bot = splited.next(); let bot_name = bot_name.into(); match bot { @@ -143,7 +143,7 @@ fn impl_parse( #( #matching_values => Ok(#variants_initialization), )* - _ => Err(ParseError::UncorrectCommand(command_raw.to_string())), + _ => Err(ParseError::UnknownCommand(command_raw.to_string())), } } }