mirror of https://github.com/zkat/miette.git
feat(help): allow non-option values in #[help] fields
This commit is contained in:
parent
23ee3642d1
commit
12bf4f78cf
|
|
@ -18,7 +18,7 @@ use crate::{
|
|||
|
||||
pub enum Help {
|
||||
Display(Display),
|
||||
Field(syn::Member),
|
||||
Field(syn::Member, Box<syn::Type>),
|
||||
}
|
||||
|
||||
impl Parse for Help {
|
||||
|
|
@ -78,7 +78,7 @@ impl Help {
|
|||
span: field.span(),
|
||||
})
|
||||
};
|
||||
return Ok(Some(Help::Field(help)));
|
||||
return Ok(Some(Help::Field(help, Box::new(field.ty.clone()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,15 +97,19 @@ impl Help {
|
|||
Self::#ident #display_pat => std::option::Option::Some(std::boxed::Box::new(format!(#fmt #args))),
|
||||
})
|
||||
}
|
||||
Help::Field(member) => {
|
||||
Help::Field(member, ty) => {
|
||||
let help = match &member {
|
||||
syn::Member::Named(ident) => ident.clone(),
|
||||
syn::Member::Unnamed(syn::Index { index, .. }) => {
|
||||
format_ident!("_{}", index)
|
||||
}
|
||||
};
|
||||
let var = quote! { __miette_internal_var };
|
||||
Some(quote! {
|
||||
Self::#ident #display_pat => #help.as_ref().map(|h| -> std::boxed::Box<dyn std::fmt::Display + 'a> { std::boxed::Box::new(format!("{}", h)) }),
|
||||
Self::#ident #display_pat => {
|
||||
use miette::macro_helpers::ToOption;
|
||||
miette::macro_helpers::OptionalWrapper::<#ty>::new().to_option(&#help).as_ref().map(|#var| -> std::boxed::Box<dyn std::fmt::Display + 'a> { std::boxed::Box::new(format!("{}", #var)) })
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -126,13 +130,17 @@ impl Help {
|
|||
}
|
||||
})
|
||||
}
|
||||
Help::Field(member) => Some(quote! {
|
||||
fn help<'a>(&'a self) -> std::option::Option<std::boxed::Box<dyn std::fmt::Display + 'a>> {
|
||||
#[allow(unused_variables, deprecated)]
|
||||
let Self #display_pat = self;
|
||||
self.#member.as_ref().map(|h| -> std::boxed::Box<dyn std::fmt::Display + 'a> { std::boxed::Box::new(format!("{}", h)) })
|
||||
}
|
||||
}),
|
||||
Help::Field(member, ty) => {
|
||||
let var = quote! { __miette_internal_var };
|
||||
Some(quote! {
|
||||
fn help<'a>(&'a self) -> std::option::Option<std::boxed::Box<dyn std::fmt::Display + 'a>> {
|
||||
#[allow(unused_variables, deprecated)]
|
||||
let Self #display_pat = self;
|
||||
use miette::macro_helpers::ToOption;
|
||||
miette::macro_helpers::OptionalWrapper::<#ty>::new().to_option(&self.#member).as_ref().map(|#var| -> std::boxed::Box<dyn std::fmt::Display + 'a> { std::boxed::Box::new(format!("{}", #var)) })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -589,6 +589,8 @@ mod eyreish;
|
|||
#[cfg(feature = "fancy-no-backtrace")]
|
||||
mod handler;
|
||||
mod handlers;
|
||||
#[doc(hidden)]
|
||||
pub mod macro_helpers;
|
||||
mod named_source;
|
||||
#[cfg(feature = "fancy")]
|
||||
mod panic;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#[doc(hidden)]
|
||||
pub trait IsOption {}
|
||||
impl <T> IsOption for Option<T> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct OptionalWrapper<T>(pub core::marker::PhantomData<T>);
|
||||
|
||||
impl<T> OptionalWrapper<T> {
|
||||
pub fn new() -> Self {
|
||||
Self(core::marker::PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait ToOption {
|
||||
#[doc(hidden)]
|
||||
fn to_option<T>(self, value: T) -> Option<T>;
|
||||
}
|
||||
|
||||
impl<T> OptionalWrapper<T> where T: IsOption {
|
||||
#[doc(hidden)]
|
||||
pub fn to_option(self, value: &T) -> &T {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToOption for &OptionalWrapper<T> {
|
||||
fn to_option<U>(self, value: U) -> Option<U> {
|
||||
Some(value)
|
||||
}
|
||||
}
|
||||
|
|
@ -292,6 +292,16 @@ fn help_field() {
|
|||
"x".to_string(),
|
||||
Baz(Some("x".into())).help().unwrap().to_string()
|
||||
);
|
||||
|
||||
#[derive(Debug, Diagnostic, Error)]
|
||||
#[error("welp")]
|
||||
#[diagnostic()]
|
||||
struct Quux(#[help] String);
|
||||
|
||||
assert_eq!(
|
||||
"x".to_string(),
|
||||
Quux("x".into()).help().unwrap().to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in New Issue