summaryrefslogtreecommitdiff
path: root/src/severity.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/severity.rs')
-rw-r--r--src/severity.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/severity.rs b/src/severity.rs
new file mode 100644
index 0000000..76126de
--- /dev/null
+++ b/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)
+ }
+ })
+ }
+}