#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use ruff_text_size::{Ranged, TextSize};
use crate::edit::Edit;
#[derive(
Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, is_macro::Is, get_size2::GetSize,
)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum Applicability {
DisplayOnly,
Unsafe,
Safe,
}
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, get_size2::GetSize)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum IsolationLevel {
Group(u32),
#[default]
NonOverlapping,
}
#[derive(Debug, PartialEq, Eq, Clone, Hash, get_size2::GetSize)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Fix {
edits: Vec<Edit>,
applicability: Applicability,
isolation_level: IsolationLevel,
}
impl Fix {
pub fn safe_edit(edit: Edit) -> Self {
Self {
edits: vec![edit],
applicability: Applicability::Safe,
isolation_level: IsolationLevel::default(),
}
}
pub fn safe_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
let mut edits: Vec<Edit> = std::iter::once(edit).chain(rest).collect();
edits.sort_by_key(|edit| (edit.start(), edit.end()));
Self {
edits,
applicability: Applicability::Safe,
isolation_level: IsolationLevel::default(),
}
}
pub fn unsafe_edit(edit: Edit) -> Self {
Self {
edits: vec![edit],
applicability: Applicability::Unsafe,
isolation_level: IsolationLevel::default(),
}
}
pub fn unsafe_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
let mut edits: Vec<Edit> = std::iter::once(edit).chain(rest).collect();
edits.sort_by_key(|edit| (edit.start(), edit.end()));
Self {
edits,
applicability: Applicability::Unsafe,
isolation_level: IsolationLevel::default(),
}
}
pub fn display_only_edit(edit: Edit) -> Self {
Self {
edits: vec![edit],
applicability: Applicability::DisplayOnly,
isolation_level: IsolationLevel::default(),
}
}
pub fn applicable_edit(edit: Edit, applicability: Applicability) -> Self {
Self {
edits: vec![edit],
applicability,
isolation_level: IsolationLevel::default(),
}
}
pub fn applicable_edits(
edit: Edit,
rest: impl IntoIterator<Item = Edit>,
applicability: Applicability,
) -> Self {
let mut edits: Vec<Edit> = std::iter::once(edit).chain(rest).collect();
edits.sort_by_key(|edit| (edit.start(), edit.end()));
Self {
edits,
applicability,
isolation_level: IsolationLevel::default(),
}
}
pub fn min_start(&self) -> Option<TextSize> {
self.edits.first().map(Edit::start)
}
pub fn edits(&self) -> &[Edit] {
&self.edits
}
pub fn into_edits(self) -> Vec<Edit> {
self.edits
}
pub fn applicability(&self) -> Applicability {
self.applicability
}
pub fn isolation(&self) -> IsolationLevel {
self.isolation_level
}
#[must_use]
pub fn isolate(mut self, isolation: IsolationLevel) -> Self {
self.isolation_level = isolation;
self
}
pub fn applies(&self, applicability: Applicability) -> bool {
self.applicability >= applicability
}
#[must_use]
pub fn with_applicability(mut self, applicability: Applicability) -> Self {
self.applicability = applicability;
self
}
}