use rpm_spec::ast::Span;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Severity {
Allow,
Warn,
Deny,
}
impl Severity {
pub fn is_silenced(self) -> bool {
matches!(self, Severity::Allow)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum LintCategory {
Style,
Correctness,
Packaging,
Performance,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum Applicability {
MachineApplicable,
MaybeIncorrect,
Manual,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Edit {
pub span: Span,
pub replacement: String,
}
impl Edit {
pub fn new(span: Span, replacement: impl Into<String>) -> Self {
Self {
span,
replacement: replacement.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Suggestion {
pub message: String,
pub edits: Vec<Edit>,
pub applicability: Applicability,
}
impl Suggestion {
pub fn new(message: impl Into<String>, edits: Vec<Edit>, applicability: Applicability) -> Self {
Self {
message: message.into(),
edits,
applicability,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Label {
pub span: Span,
pub message: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct Diagnostic {
pub lint_id: &'static str,
pub lint_name: &'static str,
pub severity: Severity,
pub message: String,
pub primary_span: Span,
pub labels: Vec<Label>,
pub suggestions: Vec<Suggestion>,
}
impl Diagnostic {
pub fn new(
meta: &'static crate::lint::LintMetadata,
severity: Severity,
message: impl Into<String>,
primary_span: Span,
) -> Self {
Self {
lint_id: meta.id,
lint_name: meta.name,
severity,
message: message.into(),
primary_span,
labels: Vec::new(),
suggestions: Vec::new(),
}
}
#[must_use]
pub fn with_label(mut self, span: Span, message: impl Into<String>) -> Self {
self.labels.push(Label {
span,
message: message.into(),
});
self
}
#[must_use]
pub fn with_suggestion(mut self, suggestion: Suggestion) -> Self {
self.suggestions.push(suggestion);
self
}
}