From 9fa60a75964dddc59ac36544db2788c8b983778f Mon Sep 17 00:00:00 2001 From: p0lunin Date: Wed, 24 Jun 2020 19:13:56 +0300 Subject: [PATCH] fixed rust could not infer types --- src/fields_parse.rs | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/fields_parse.rs b/src/fields_parse.rs index 3b38c38f..163b4f4e 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::{FieldsNamed, FieldsUnnamed}; +use syn::{FieldsNamed, FieldsUnnamed, Type}; #[derive(Debug)] pub enum ParserType { @@ -26,7 +26,7 @@ pub fn impl_parse_args_unnamed( variant: impl ToTokens, parser_type: &ParserType, ) -> quote::__private::TokenStream { - let get_arguments = create_parser(parser_type, data.unnamed.len()); + let get_arguments = create_parser(parser_type, data.unnamed.iter().map(|f| &f.ty), data.unnamed.len()); let iter = 0..data.unnamed.len(); let mut initialization = quote! {}; for i in iter { @@ -46,7 +46,7 @@ pub fn impl_parse_args_named( variant: impl ToTokens, parser_type: &ParserType, ) -> quote::__private::TokenStream { - let get_arguments = create_parser(parser_type, data.named.len()); + let get_arguments = create_parser(parser_type, data.named.iter().map(|f| &f.ty), data.named.len()); let i = 0..data.named.len(); let name = data.named.iter().map(|f| f.ident.as_ref().unwrap()); let res = quote! { @@ -58,16 +58,16 @@ pub fn impl_parse_args_named( res } -fn create_parser(parser_type: &ParserType, count_args: usize) -> quote::__private::TokenStream { +fn create_parser<'a>(parser_type: &ParserType, types: impl Iterator, 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::IncorrectFormat)?,)) ) } + quote! { (|s: String| Ok((s,))) } } _ => quote! { compile_error!("Expected 1 argument") }, }, ParserType::Split { separator } => { - parser_with_separator(&separator.clone().unwrap_or(" ".to_owned()), count_args) + parser_with_separator(&separator.clone().unwrap_or(" ".to_owned()), types, count_args) } ParserType::Custom(s) => { let ident = syn::Ident::new(&s, Span::call_site()); @@ -79,18 +79,17 @@ fn create_parser(parser_type: &ParserType, count_args: usize) -> quote::__privat } } -fn parser_with_separator(separator: &str, count_args: usize) -> quote::__private::TokenStream { +fn parser_with_separator<'a>(separator: &str, types: impl Iterator, count_args: usize) -> quote::__private::TokenStream { 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.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 i = 0..count_args; + let inner2 = + quote! { + #(#types::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(|e|ParseError::IncorrectFormat({ let e: Box = e.into(); e }))?,)* + }; let res = quote! { (|s: String| { #inner