mirror of https://github.com/zkat/miette.git
fix(derive): allow #[label] on Option<T> when T: !Copy
This commit is contained in:
parent
df7bcfa17d
commit
62c74617d0
|
|
@ -105,6 +105,16 @@ impl Parse for LabelAttr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if a type is syntactically `Option<...>`.
|
||||||
|
fn is_option_type(ty: &syn::Type) -> bool {
|
||||||
|
if let syn::Type::Path(type_path) = ty {
|
||||||
|
if let Some(segment) = type_path.path.segments.last() {
|
||||||
|
return segment.ident == "Option";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
impl Labels {
|
impl Labels {
|
||||||
pub fn from_fields(fields: &syn::Fields) -> syn::Result<Option<Self>> {
|
pub fn from_fields(fields: &syn::Fields) -> syn::Result<Option<Self>> {
|
||||||
match fields {
|
match fields {
|
||||||
|
|
@ -185,13 +195,23 @@ impl Labels {
|
||||||
quote! { miette::LabeledSpan::new_with_span }
|
quote! { miette::LabeledSpan::new_with_span }
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(quote! {
|
let label_code = if is_option_type(ty) {
|
||||||
miette::macro_helpers::OptionalWrapper::<#ty>::new().to_option(&self.#span)
|
quote! {
|
||||||
.map(|#var| #ctor(
|
self.#span.as_ref().map(|#var| #ctor(
|
||||||
#display,
|
#display,
|
||||||
#var.clone(),
|
#var.clone(),
|
||||||
))
|
))
|
||||||
})
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
miette::macro_helpers::OptionalWrapper::<#ty>::new().to_option(&self.#span)
|
||||||
|
.map(|#var| #ctor(
|
||||||
|
#display,
|
||||||
|
#var.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(label_code)
|
||||||
});
|
});
|
||||||
let collections_chain = self.0.iter().filter_map(|label| {
|
let collections_chain = self.0.iter().filter_map(|label| {
|
||||||
let Label {
|
let Label {
|
||||||
|
|
@ -272,13 +292,23 @@ impl Labels {
|
||||||
quote! { miette::LabeledSpan::new_with_span }
|
quote! { miette::LabeledSpan::new_with_span }
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(quote! {
|
let variant_label_code = if is_option_type(ty) {
|
||||||
miette::macro_helpers::OptionalWrapper::<#ty>::new().to_option(#field)
|
quote! {
|
||||||
.map(|#var| #ctor(
|
#field.as_ref().map(|#var| #ctor(
|
||||||
#display,
|
#display,
|
||||||
#var.clone(),
|
#var.clone(),
|
||||||
))
|
))
|
||||||
})
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
miette::macro_helpers::OptionalWrapper::<#ty>::new().to_option(#field)
|
||||||
|
.map(|#var| #ctor(
|
||||||
|
#display,
|
||||||
|
#var.clone(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(variant_label_code)
|
||||||
});
|
});
|
||||||
let collections_chain = labels.0.iter().filter_map(|label| {
|
let collections_chain = labels.0.iter().filter_map(|label| {
|
||||||
let Label { span, label, ty: _, lbl_ty } = label;
|
let Label { span, label, ty: _, lbl_ty } = label;
|
||||||
|
|
|
||||||
|
|
@ -632,3 +632,39 @@ fn test_optional_source_code() {
|
||||||
.source_code()
|
.source_code()
|
||||||
.is_some());
|
.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_label_option_non_copy() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NonCopySpan(SourceSpan);
|
||||||
|
|
||||||
|
impl From<NonCopySpan> for SourceSpan {
|
||||||
|
fn from(v: NonCopySpan) -> Self {
|
||||||
|
v.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<&NonCopySpan> for SourceSpan {
|
||||||
|
fn from(v: &NonCopySpan) -> Self {
|
||||||
|
v.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
|
#[error("test error")]
|
||||||
|
struct E {
|
||||||
|
#[source_code]
|
||||||
|
src: String,
|
||||||
|
#[label("here")]
|
||||||
|
span: Option<NonCopySpan>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let e = E {
|
||||||
|
src: "hello there".into(),
|
||||||
|
span: Some(NonCopySpan((0..5).into())),
|
||||||
|
};
|
||||||
|
let labels: Vec<_> = e.labels().unwrap().collect();
|
||||||
|
assert_eq!(labels.len(), 1);
|
||||||
|
assert_eq!(labels[0].offset(), 0);
|
||||||
|
assert_eq!(labels[0].len(), 5);
|
||||||
|
assert_eq!(labels[0].label(), Some("here"));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue