use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum DeriveStrategy {
#[default]
TryAddDerive,
GenerateImpl,
SkipAndReport,
ImmediateError,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum MatchUpdateStrategy {
#[default]
AddWildcard,
AddExplicitArm(String),
AddTodo,
AddUnreachable,
Interactive,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum FieldInitStrategy {
#[default]
UseDefault,
WithValue(String),
AddToConstructor,
UseBuilder,
Interactive,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum ReferenceUpdateStrategy {
#[default]
UpdateAll,
SameCrateOnly,
SpecificFiles(Vec<PathBuf>),
ReportOnly,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum RemovalStrategy {
RemoveAllReferences,
#[default]
ReportOnly,
DeprecateFirst {
warning_message: String,
},
MigrateTo {
replacement: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ErrorStrategy {
#[default]
StopAndReport,
ContinueWithWarning,
SkipAndContinue,
Rollback,
}
#[derive(Debug, Clone, Default)]
pub struct CascadeStrategy {
pub derive: DeriveStrategy,
pub match_update: MatchUpdateStrategy,
pub field_init: FieldInitStrategy,
pub reference_update: ReferenceUpdateStrategy,
pub removal: RemovalStrategy,
pub on_error: ErrorStrategy,
}
impl CascadeStrategy {
pub fn safe() -> Self {
Self {
derive: DeriveStrategy::TryAddDerive,
match_update: MatchUpdateStrategy::AddTodo,
field_init: FieldInitStrategy::UseDefault,
reference_update: ReferenceUpdateStrategy::UpdateAll,
removal: RemovalStrategy::DeprecateFirst {
warning_message: "This item will be removed in a future version".to_string(),
},
on_error: ErrorStrategy::StopAndReport,
}
}
pub fn aggressive() -> Self {
Self {
derive: DeriveStrategy::TryAddDerive,
match_update: MatchUpdateStrategy::AddWildcard,
field_init: FieldInitStrategy::UseDefault,
reference_update: ReferenceUpdateStrategy::UpdateAll,
removal: RemovalStrategy::RemoveAllReferences,
on_error: ErrorStrategy::ContinueWithWarning,
}
}
pub fn interactive() -> Self {
Self {
derive: DeriveStrategy::TryAddDerive,
match_update: MatchUpdateStrategy::Interactive,
field_init: FieldInitStrategy::Interactive,
reference_update: ReferenceUpdateStrategy::UpdateAll,
removal: RemovalStrategy::ReportOnly,
on_error: ErrorStrategy::StopAndReport,
}
}
pub fn eager() -> Self {
Self::default()
}
pub fn lazy() -> Self {
Self {
derive: DeriveStrategy::SkipAndReport,
..Self::default()
}
}
pub fn is_eager(&self) -> bool {
matches!(
self.derive,
DeriveStrategy::TryAddDerive | DeriveStrategy::GenerateImpl
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_strategy() {
let strategy = CascadeStrategy::default();
assert_eq!(strategy.derive, DeriveStrategy::TryAddDerive);
assert_eq!(strategy.match_update, MatchUpdateStrategy::AddWildcard);
assert_eq!(strategy.on_error, ErrorStrategy::StopAndReport);
}
#[test]
fn test_safe_strategy() {
let strategy = CascadeStrategy::safe();
assert!(matches!(
strategy.removal,
RemovalStrategy::DeprecateFirst { .. }
));
assert_eq!(strategy.on_error, ErrorStrategy::StopAndReport);
}
#[test]
fn test_aggressive_strategy() {
let strategy = CascadeStrategy::aggressive();
assert_eq!(strategy.removal, RemovalStrategy::RemoveAllReferences);
assert_eq!(strategy.on_error, ErrorStrategy::ContinueWithWarning);
}
}