1use std::path::PathBuf;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10pub enum DeriveStrategy {
11 #[default]
13 TryAddDerive,
14
15 GenerateImpl,
17
18 SkipAndReport,
20
21 ImmediateError,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, Default)]
27pub enum MatchUpdateStrategy {
28 #[default]
30 AddWildcard,
31
32 AddExplicitArm(String),
34
35 AddTodo,
37
38 AddUnreachable,
40
41 Interactive,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq, Default)]
47pub enum FieldInitStrategy {
48 #[default]
50 UseDefault,
51
52 WithValue(String),
54
55 AddToConstructor,
57
58 UseBuilder,
60
61 Interactive,
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Default)]
67pub enum ReferenceUpdateStrategy {
68 #[default]
70 UpdateAll,
71
72 SameCrateOnly,
74
75 SpecificFiles(Vec<PathBuf>),
77
78 ReportOnly,
80}
81
82#[derive(Debug, Clone, PartialEq, Eq, Default)]
84pub enum RemovalStrategy {
85 RemoveAllReferences,
87
88 #[default]
90 ReportOnly,
91
92 DeprecateFirst {
94 warning_message: String,
96 },
97
98 MigrateTo {
100 replacement: String,
102 },
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
107pub enum ErrorStrategy {
108 #[default]
110 StopAndReport,
111
112 ContinueWithWarning,
114
115 SkipAndContinue,
117
118 Rollback,
120}
121
122#[derive(Debug, Clone, Default)]
124pub struct CascadeStrategy {
125 pub derive: DeriveStrategy,
127
128 pub match_update: MatchUpdateStrategy,
130
131 pub field_init: FieldInitStrategy,
133
134 pub reference_update: ReferenceUpdateStrategy,
136
137 pub removal: RemovalStrategy,
139
140 pub on_error: ErrorStrategy,
142}
143
144impl CascadeStrategy {
145 pub fn safe() -> Self {
151 Self {
152 derive: DeriveStrategy::TryAddDerive,
153 match_update: MatchUpdateStrategy::AddTodo,
154 field_init: FieldInitStrategy::UseDefault,
155 reference_update: ReferenceUpdateStrategy::UpdateAll,
156 removal: RemovalStrategy::DeprecateFirst {
157 warning_message: "This item will be removed in a future version".to_string(),
158 },
159 on_error: ErrorStrategy::StopAndReport,
160 }
161 }
162
163 pub fn aggressive() -> Self {
169 Self {
170 derive: DeriveStrategy::TryAddDerive,
171 match_update: MatchUpdateStrategy::AddWildcard,
172 field_init: FieldInitStrategy::UseDefault,
173 reference_update: ReferenceUpdateStrategy::UpdateAll,
174 removal: RemovalStrategy::RemoveAllReferences,
175 on_error: ErrorStrategy::ContinueWithWarning,
176 }
177 }
178
179 pub fn interactive() -> Self {
181 Self {
182 derive: DeriveStrategy::TryAddDerive,
183 match_update: MatchUpdateStrategy::Interactive,
184 field_init: FieldInitStrategy::Interactive,
185 reference_update: ReferenceUpdateStrategy::UpdateAll,
186 removal: RemovalStrategy::ReportOnly,
187 on_error: ErrorStrategy::StopAndReport,
188 }
189 }
190
191 pub fn eager() -> Self {
193 Self::default()
194 }
195
196 pub fn lazy() -> Self {
198 Self {
199 derive: DeriveStrategy::SkipAndReport,
200 ..Self::default()
201 }
202 }
203
204 pub fn is_eager(&self) -> bool {
206 matches!(
207 self.derive,
208 DeriveStrategy::TryAddDerive | DeriveStrategy::GenerateImpl
209 )
210 }
211}
212
213#[cfg(test)]
214mod tests {
215 use super::*;
216
217 #[test]
218 fn test_default_strategy() {
219 let strategy = CascadeStrategy::default();
220 assert_eq!(strategy.derive, DeriveStrategy::TryAddDerive);
221 assert_eq!(strategy.match_update, MatchUpdateStrategy::AddWildcard);
222 assert_eq!(strategy.on_error, ErrorStrategy::StopAndReport);
223 }
224
225 #[test]
226 fn test_safe_strategy() {
227 let strategy = CascadeStrategy::safe();
228 assert!(matches!(
229 strategy.removal,
230 RemovalStrategy::DeprecateFirst { .. }
231 ));
232 assert_eq!(strategy.on_error, ErrorStrategy::StopAndReport);
233 }
234
235 #[test]
236 fn test_aggressive_strategy() {
237 let strategy = CascadeStrategy::aggressive();
238 assert_eq!(strategy.removal, RemovalStrategy::RemoveAllReferences);
239 assert_eq!(strategy.on_error, ErrorStrategy::ContinueWithWarning);
240 }
241}