1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4use ruff_text_size::{Ranged, TextSize};
5
6use crate::edit::Edit;
7
8#[derive(
10 Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, is_macro::Is, get_size2::GetSize,
11)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
14pub enum Applicability {
15 DisplayOnly,
19
20 Unsafe,
26
27 Safe,
32}
33
34#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, get_size2::GetSize)]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37pub enum IsolationLevel {
38 Group(u32),
40 #[default]
42 NonOverlapping,
43}
44
45#[derive(Debug, PartialEq, Eq, Clone, Hash, get_size2::GetSize)]
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48pub struct Fix {
49 edits: Vec<Edit>,
51 applicability: Applicability,
53 isolation_level: IsolationLevel,
55}
56
57impl Fix {
58 pub fn safe_edit(edit: Edit) -> Self {
60 Self {
61 edits: vec![edit],
62 applicability: Applicability::Safe,
63 isolation_level: IsolationLevel::default(),
64 }
65 }
66
67 pub fn safe_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
69 let mut edits: Vec<Edit> = std::iter::once(edit).chain(rest).collect();
70 edits.sort_by_key(|edit| (edit.start(), edit.end()));
71 Self {
72 edits,
73 applicability: Applicability::Safe,
74 isolation_level: IsolationLevel::default(),
75 }
76 }
77
78 pub fn unsafe_edit(edit: Edit) -> Self {
80 Self {
81 edits: vec![edit],
82 applicability: Applicability::Unsafe,
83 isolation_level: IsolationLevel::default(),
84 }
85 }
86
87 pub fn unsafe_edits(edit: Edit, rest: impl IntoIterator<Item = Edit>) -> Self {
89 let mut edits: Vec<Edit> = std::iter::once(edit).chain(rest).collect();
90 edits.sort_by_key(|edit| (edit.start(), edit.end()));
91 Self {
92 edits,
93 applicability: Applicability::Unsafe,
94 isolation_level: IsolationLevel::default(),
95 }
96 }
97
98 pub fn display_only_edit(edit: Edit) -> Self {
100 Self {
101 edits: vec![edit],
102 applicability: Applicability::DisplayOnly,
103 isolation_level: IsolationLevel::default(),
104 }
105 }
106
107 pub fn applicable_edit(edit: Edit, applicability: Applicability) -> Self {
109 Self {
110 edits: vec![edit],
111 applicability,
112 isolation_level: IsolationLevel::default(),
113 }
114 }
115
116 pub fn applicable_edits(
118 edit: Edit,
119 rest: impl IntoIterator<Item = Edit>,
120 applicability: Applicability,
121 ) -> Self {
122 let mut edits: Vec<Edit> = std::iter::once(edit).chain(rest).collect();
123 edits.sort_by_key(|edit| (edit.start(), edit.end()));
124 Self {
125 edits,
126 applicability,
127 isolation_level: IsolationLevel::default(),
128 }
129 }
130
131 pub fn min_start(&self) -> Option<TextSize> {
133 self.edits.first().map(Edit::start)
134 }
135
136 pub fn edits(&self) -> &[Edit] {
138 &self.edits
139 }
140
141 pub fn into_edits(self) -> Vec<Edit> {
142 self.edits
143 }
144
145 pub fn applicability(&self) -> Applicability {
147 self.applicability
148 }
149
150 pub fn isolation(&self) -> IsolationLevel {
152 self.isolation_level
153 }
154
155 #[must_use]
157 pub fn isolate(mut self, isolation: IsolationLevel) -> Self {
158 self.isolation_level = isolation;
159 self
160 }
161
162 pub fn applies(&self, applicability: Applicability) -> bool {
164 self.applicability >= applicability
165 }
166
167 #[must_use]
169 pub fn with_applicability(mut self, applicability: Applicability) -> Self {
170 self.applicability = applicability;
171 self
172 }
173}