use serde::Serialize;
use super::ScoopError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[repr(u8)]
pub enum MigrationExitCode {
Success = 0,
PartialSuccess = 1,
CompleteFailure = 2,
SourceError = 3,
}
impl ScoopError {
pub fn migration_exit_code(&self) -> MigrationExitCode {
match self {
Self::PyenvNotFound
| Self::PyenvEnvNotFound { .. }
| Self::VenvWrapperEnvNotFound { .. }
| Self::CondaEnvNotFound { .. }
| Self::CorruptedEnvironment { .. }
| Self::MigrationSourcesNotFound { .. } => MigrationExitCode::SourceError,
_ => MigrationExitCode::CompleteFailure,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
#[test]
fn source_tool_variants_map_to_source_error() {
let cases = [
ScoopError::PyenvNotFound,
ScoopError::PyenvEnvNotFound {
name: "x".to_string(),
},
ScoopError::VenvWrapperEnvNotFound {
name: "x".to_string(),
},
ScoopError::CondaEnvNotFound {
name: "x".to_string(),
},
ScoopError::CorruptedEnvironment {
name: "x".to_string(),
reason: "y".to_string(),
},
ScoopError::MigrationSourcesNotFound {
requested: Some("pyenv".to_string()),
},
ScoopError::MigrationSourcesNotFound { requested: None },
];
for err in cases {
assert_eq!(
err.migration_exit_code(),
MigrationExitCode::SourceError,
"{err:?} should map to SourceError"
);
}
}
#[test]
fn migration_internal_variants_map_to_complete_failure() {
let cases = [
ScoopError::MigrationFailed {
reason: "boom".to_string(),
},
ScoopError::MigrationNameConflict {
name: "x".to_string(),
existing: PathBuf::from("/y"),
},
];
for err in cases {
assert_eq!(
err.migration_exit_code(),
MigrationExitCode::CompleteFailure,
"{err:?} should map to CompleteFailure"
);
}
}
#[test]
fn unrelated_variants_use_catchall_complete_failure() {
let err = ScoopError::UvNotFound;
assert_eq!(
err.migration_exit_code(),
MigrationExitCode::CompleteFailure
);
}
}