extern crate alloc;
use alloc::vec::Vec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Evolution {
AddOperation,
RemoveOperation,
ReorderOperations,
ReorderBaseInterfaces,
ChangeSignature,
DuckTyping,
AddRemoveParameter,
ReorderParameters,
ChangeParameterType,
AddRemoveReturnType,
ChangeReturnType,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mapping {
Basic,
Enhanced,
}
#[must_use]
pub fn is_compatible(mapping: Mapping, evolution: Evolution) -> bool {
match (mapping, evolution) {
(Mapping::Basic, _) => false,
(Mapping::Enhanced, Evolution::AddOperation) => true,
(Mapping::Enhanced, Evolution::RemoveOperation) => true, (Mapping::Enhanced, Evolution::ReorderOperations) => true,
(Mapping::Enhanced, Evolution::ReorderBaseInterfaces) => true,
(Mapping::Enhanced, Evolution::DuckTyping) => true,
(Mapping::Enhanced, Evolution::AddRemoveParameter) => true,
(Mapping::Enhanced, Evolution::ReorderParameters) => true,
(Mapping::Enhanced, Evolution::AddRemoveReturnType) => true,
(Mapping::Enhanced, Evolution::ChangeSignature) => false,
(Mapping::Enhanced, Evolution::ChangeParameterType) => false,
(Mapping::Enhanced, Evolution::ChangeReturnType) => false,
}
}
#[must_use]
pub fn compatible_evolutions(mapping: Mapping) -> Vec<Evolution> {
[
Evolution::AddOperation,
Evolution::RemoveOperation,
Evolution::ReorderOperations,
Evolution::ReorderBaseInterfaces,
Evolution::ChangeSignature,
Evolution::DuckTyping,
Evolution::AddRemoveParameter,
Evolution::ReorderParameters,
Evolution::ChangeParameterType,
Evolution::AddRemoveReturnType,
Evolution::ChangeReturnType,
]
.iter()
.copied()
.filter(|e| is_compatible(mapping, *e))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic_mapping_add_remove_operation_is_breaking() {
assert!(!is_compatible(Mapping::Basic, Evolution::AddOperation));
assert!(!is_compatible(Mapping::Basic, Evolution::RemoveOperation));
}
#[test]
fn basic_mapping_reorder_operations_is_breaking() {
assert!(!is_compatible(Mapping::Basic, Evolution::ReorderOperations));
assert!(!is_compatible(
Mapping::Basic,
Evolution::ReorderBaseInterfaces
));
}
#[test]
fn basic_mapping_change_signature_is_breaking() {
assert!(!is_compatible(Mapping::Basic, Evolution::ChangeSignature));
}
#[test]
fn basic_mapping_has_no_compatible_evolutions() {
assert!(compatible_evolutions(Mapping::Basic).is_empty());
}
#[test]
fn enhanced_mapping_add_operation_is_compatible() {
assert!(is_compatible(Mapping::Enhanced, Evolution::AddOperation));
}
#[test]
fn enhanced_mapping_remove_operation_is_compatible_with_caveat() {
assert!(is_compatible(Mapping::Enhanced, Evolution::RemoveOperation));
}
#[test]
fn enhanced_mapping_reorder_operations_is_compatible() {
assert!(is_compatible(
Mapping::Enhanced,
Evolution::ReorderOperations
));
assert!(is_compatible(
Mapping::Enhanced,
Evolution::ReorderBaseInterfaces
));
}
#[test]
fn enhanced_mapping_duck_typing_is_compatible() {
assert!(is_compatible(Mapping::Enhanced, Evolution::DuckTyping));
}
#[test]
fn enhanced_mapping_add_remove_param_is_compatible() {
assert!(is_compatible(
Mapping::Enhanced,
Evolution::AddRemoveParameter
));
}
#[test]
fn enhanced_mapping_reorder_params_is_compatible() {
assert!(is_compatible(
Mapping::Enhanced,
Evolution::ReorderParameters
));
}
#[test]
fn enhanced_mapping_change_param_type_is_breaking() {
assert!(!is_compatible(
Mapping::Enhanced,
Evolution::ChangeParameterType
));
}
#[test]
fn enhanced_mapping_add_remove_return_type_is_compatible() {
assert!(is_compatible(
Mapping::Enhanced,
Evolution::AddRemoveReturnType
));
}
#[test]
fn enhanced_mapping_change_return_type_is_breaking() {
assert!(!is_compatible(
Mapping::Enhanced,
Evolution::ChangeReturnType
));
}
#[test]
fn enhanced_compatible_evolutions_includes_8_of_11() {
let compats = compatible_evolutions(Mapping::Enhanced);
assert_eq!(compats.len(), 8);
}
}