diff options
Diffstat (limited to 'vendor/miette-derive/src/severity.rs')
-rw-r--r-- | vendor/miette-derive/src/severity.rs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/vendor/miette-derive/src/severity.rs b/vendor/miette-derive/src/severity.rs new file mode 100644 index 0000000..4f26e4e --- /dev/null +++ b/vendor/miette-derive/src/severity.rs @@ -0,0 +1,89 @@ +use proc_macro2::{Span, TokenStream}; +use quote::quote; +use syn::{ + parenthesized, + parse::{Parse, ParseStream}, + Token, +}; + +use crate::{ + diagnostic::{DiagnosticConcreteArgs, DiagnosticDef}, + forward::WhichFn, + utils::gen_all_variants_with, +}; + +pub struct Severity(pub syn::Ident); + +impl Parse for Severity { + fn parse(input: ParseStream) -> syn::Result<Self> { + let ident = input.parse::<syn::Ident>()?; + if ident == "severity" { + let la = input.lookahead1(); + if la.peek(syn::token::Paren) { + let content; + parenthesized!(content in input); + let la = content.lookahead1(); + if la.peek(syn::LitStr) { + let str = content.parse::<syn::LitStr>()?; + let sev = get_severity(&str.value(), str.span())?; + Ok(Severity(syn::Ident::new(&sev, str.span()))) + } else { + let ident = content.parse::<syn::Ident>()?; + let sev = get_severity(&ident.to_string(), ident.span())?; + Ok(Severity(syn::Ident::new(&sev, ident.span()))) + } + } else { + input.parse::<Token![=]>()?; + let str = input.parse::<syn::LitStr>()?; + let sev = get_severity(&str.value(), str.span())?; + Ok(Severity(syn::Ident::new(&sev, str.span()))) + } + } else { + Err(syn::Error::new( + ident.span(), + "MIETTE BUG: not a severity option", + )) + } + } +} + +fn get_severity(input: &str, span: Span) -> syn::Result<String> { + match input.to_lowercase().as_ref() { + "error" | "err" => Ok("Error".into()), + "warning" | "warn" => Ok("Warning".into()), + "advice" | "adv" | "info" => Ok("Advice".into()), + _ => Err(syn::Error::new( + span, + "Invalid severity level. Only Error, Warning, and Advice are supported.", + )), + } +} + +impl Severity { + pub(crate) fn gen_enum(variants: &[DiagnosticDef]) -> Option<TokenStream> { + gen_all_variants_with( + variants, + WhichFn::Severity, + |ident, fields, DiagnosticConcreteArgs { severity, .. }| { + let severity = &severity.as_ref()?.0; + let fields = match fields { + syn::Fields::Named(_) => quote! { { .. } }, + syn::Fields::Unnamed(_) => quote! { (..) }, + syn::Fields::Unit => quote! {}, + }; + Some( + quote! { Self::#ident #fields => std::option::Option::Some(miette::Severity::#severity), }, + ) + }, + ) + } + + pub(crate) fn gen_struct(&self) -> Option<TokenStream> { + let sev = &self.0; + Some(quote! { + fn severity(&self) -> std::option::Option<miette::Severity> { + Some(miette::Severity::#sev) + } + }) + } +} |