From 9ef0dd261fa537b280f32ea6f149785a69e33938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Sun, 15 Aug 2021 18:15:50 -0700 Subject: [PATCH] feat(derive): improved derive support, including partial help format string support! --- miette-derive/src/help.rs | 42 +++++++++++++++++++++++++++++++-------- tests/derive.rs | 6 ++---- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/miette-derive/src/help.rs b/miette-derive/src/help.rs index a974d40..22e98b6 100644 --- a/miette-derive/src/help.rs +++ b/miette-derive/src/help.rs @@ -21,11 +21,37 @@ impl Parse for Help { if la.peek(syn::token::Paren) { let content; parenthesized!(content in input); - let str = content.parse::()?; - Ok(Help { - fmt: str.value(), - args: Vec::new(), - }) + let mut fmt = None; + let mut args = Vec::new(); + let punc = syn::punctuated::Punctuated::::parse_terminated( + &content, + )?; + for (i, arg) in punc.into_iter().enumerate() { + if i == 0 { + if let syn::Expr::Lit(syn::ExprLit { + lit: syn::Lit::Str(str), + .. + }) = arg + { + fmt = Some(str.value()); + } + } else { + args.push(arg); + } + } + if let Some(fmt) = fmt { + Ok(Help { fmt, args }) + } else if !args.is_empty() { + Err(syn::Error::new( + ident.span(), + "The first arg to help() must be a literal format string.", + )) + } else { + Err(syn::Error::new( + ident.span(), + "help() format string is required", + )) + } } else { input.parse::()?; Ok(Help { @@ -53,9 +79,9 @@ impl Help { ref fields, .. }| { - let help = &help.as_ref().unwrap(); - let fmt = &help.fmt; - let args = help.args.iter().map(|arg| quote! { #arg, }); + let help = &help.as_ref().unwrap(); + let fmt = &help.fmt; + let args = &help.args; match fields { syn::Fields::Named(_) => { quote! { Self::#ident{..} => std::option::Option::Some(std::boxed::Box::new(format!(#fmt, #(#args),*))), } diff --git a/tests/derive.rs b/tests/derive.rs index ef286e7..55c20c2 100644 --- a/tests/derive.rs +++ b/tests/derive.rs @@ -132,7 +132,6 @@ fn list_help() { ); } -/* #[test] fn fmt_help() { #[derive(Debug, Diagnostic, Error)] @@ -144,8 +143,8 @@ fn fmt_help() { struct FooStruct(String); assert_eq!( - "1 bar".to_string(), - FooStruct.help().unwrap().to_string() + "1 hello".to_string(), + FooStruct("hello".into()).help().unwrap().to_string() ); #[derive(Debug, Diagnostic, Error)] @@ -163,4 +162,3 @@ fn fmt_help() { FooEnum::X.help().unwrap().to_string() ); } -*/