#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CppVerdict {
Pass,
Fail,
}
#[must_use]
pub fn verdict_from_class_to_struct(
cpp_field_count: u32,
rust_pub_field_count: u32,
rust_has_struct: bool,
) -> CppVerdict {
if !rust_has_struct {
return CppVerdict::Fail;
}
if cpp_field_count == rust_pub_field_count {
CppVerdict::Pass
} else {
CppVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_ctor_to_new(
cpp_has_ctor: bool,
rust_has_pub_fn_new: bool,
rust_returns_self: bool,
) -> CppVerdict {
if !cpp_has_ctor {
return CppVerdict::Pass; }
if rust_has_pub_fn_new && rust_returns_self {
CppVerdict::Pass
} else {
CppVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_dtor_to_drop(
cpp_has_dtor: bool,
rust_has_impl_drop: bool,
) -> CppVerdict {
if !cpp_has_dtor {
return CppVerdict::Pass;
}
if rust_has_impl_drop {
CppVerdict::Pass
} else {
CppVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_namespace_to_mod(
cpp_namespace_name: &str,
rust_mod_name: &str,
rust_mod_has_pub_visibility: bool,
) -> CppVerdict {
if cpp_namespace_name.is_empty() {
return CppVerdict::Fail;
}
if cpp_namespace_name == rust_mod_name && rust_mod_has_pub_visibility {
CppVerdict::Pass
} else {
CppVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_operator_plus_to_add(
cpp_has_operator_plus: bool,
rust_has_impl_add: bool,
) -> CppVerdict {
if !cpp_has_operator_plus {
return CppVerdict::Pass;
}
if rust_has_impl_add {
CppVerdict::Pass
} else {
CppVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_inheritance_to_deref(
cpp_has_base_class: bool,
rust_has_base_field: bool,
rust_has_impl_deref: bool,
) -> CppVerdict {
if !cpp_has_base_class {
return CppVerdict::Pass;
}
if rust_has_base_field && rust_has_impl_deref {
CppVerdict::Pass
} else {
CppVerdict::Fail
}
}
#[must_use]
pub fn verdict_from_this_to_self(
cpp_implicit_field_accesses: u32,
rust_self_field_accesses: u32,
) -> CppVerdict {
if cpp_implicit_field_accesses == 0 {
return CppVerdict::Pass; }
if cpp_implicit_field_accesses == rust_self_field_accesses {
CppVerdict::Pass
} else {
CppVerdict::Fail
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fcpp001_pass_2_field_class() {
let v = verdict_from_class_to_struct(2, 2, true);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp001_fail_field_count_mismatch() {
let v = verdict_from_class_to_struct(2, 1, true);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp001_fail_no_struct_emitted() {
let v = verdict_from_class_to_struct(2, 2, false);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp002_pass_ctor_to_new_returning_self() {
let v = verdict_from_ctor_to_new(true, true, true);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp002_pass_no_ctor_in_source() {
let v = verdict_from_ctor_to_new(false, false, false);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp002_fail_ctor_no_new() {
let v = verdict_from_ctor_to_new(true, false, false);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp002_fail_new_returns_other() {
let v = verdict_from_ctor_to_new(true, true, false);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp003_pass_dtor_to_drop() {
let v = verdict_from_dtor_to_drop(true, true);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp003_pass_no_dtor() {
let v = verdict_from_dtor_to_drop(false, false);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp003_fail_dtor_no_drop() {
let v = verdict_from_dtor_to_drop(true, false);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp004_pass_math_to_pub_mod_math() {
let v = verdict_from_namespace_to_mod("math", "math", true);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp004_fail_name_drift() {
let v = verdict_from_namespace_to_mod("math", "maths", true);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp004_fail_private_mod() {
let v = verdict_from_namespace_to_mod("math", "math", false);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp004_fail_empty_name() {
let v = verdict_from_namespace_to_mod("", "", true);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp005_pass_operator_plus_to_add() {
let v = verdict_from_operator_plus_to_add(true, true);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp005_pass_no_operator_plus() {
let v = verdict_from_operator_plus_to_add(false, false);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp005_fail_operator_plus_no_add() {
let v = verdict_from_operator_plus_to_add(true, false);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp006_pass_inheritance_with_base_and_deref() {
let v = verdict_from_inheritance_to_deref(true, true, true);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp006_pass_no_base_class() {
let v = verdict_from_inheritance_to_deref(false, false, false);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp006_fail_missing_base_field() {
let v = verdict_from_inheritance_to_deref(true, false, true);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp006_fail_missing_deref_impl() {
let v = verdict_from_inheritance_to_deref(true, true, false);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp007_pass_3_implicit_3_self() {
let v = verdict_from_this_to_self(3, 3);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp007_pass_no_implicit_this() {
let v = verdict_from_this_to_self(0, 0);
assert_eq!(v, CppVerdict::Pass);
}
#[test]
fn fcpp007_fail_count_mismatch() {
let v = verdict_from_this_to_self(3, 2);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn fcpp007_fail_dropped_all_self() {
let v = verdict_from_this_to_self(3, 0);
assert_eq!(v, CppVerdict::Fail);
}
#[test]
fn mutation_survey_001_field_count_band() {
for n in [0_u32, 1, 2, 5, 10] {
let v = verdict_from_class_to_struct(n, n, true);
assert_eq!(v, CppVerdict::Pass, "n={n}");
}
}
#[test]
fn mutation_survey_007_implicit_this_band() {
for n in [0_u32, 1, 5, 100] {
let v = verdict_from_this_to_self(n, n);
assert_eq!(v, CppVerdict::Pass, "n={n}");
if n > 0 {
let v_off = verdict_from_this_to_self(n, n - 1);
assert_eq!(v_off, CppVerdict::Fail, "n={n}");
}
}
}
#[test]
fn realistic_healthy_passes_all_7() {
let v1 = verdict_from_class_to_struct(2, 2, true);
let v2 = verdict_from_ctor_to_new(true, true, true);
let v3 = verdict_from_dtor_to_drop(true, true);
let v4 = verdict_from_namespace_to_mod("math", "math", true);
let v5 = verdict_from_operator_plus_to_add(true, true);
let v6 = verdict_from_inheritance_to_deref(true, true, true);
let v7 = verdict_from_this_to_self(3, 3);
for v in [v1, v2, v3, v4, v5, v6, v7] {
assert_eq!(v, CppVerdict::Pass);
}
}
#[test]
fn realistic_pre_fix_all_7_failures() {
let v1 = verdict_from_class_to_struct(2, 1, true); let v2 = verdict_from_ctor_to_new(true, false, false); let v3 = verdict_from_dtor_to_drop(true, false); let v4 = verdict_from_namespace_to_mod("math", "math", false); let v5 = verdict_from_operator_plus_to_add(true, false); let v6 = verdict_from_inheritance_to_deref(true, false, true); let v7 = verdict_from_this_to_self(3, 0); for v in [v1, v2, v3, v4, v5, v6, v7] {
assert_eq!(v, CppVerdict::Fail);
}
}
#[test]
fn vacuous_pass_for_unused_features() {
let v3 = verdict_from_dtor_to_drop(false, false);
let v5 = verdict_from_operator_plus_to_add(false, false);
let v6 = verdict_from_inheritance_to_deref(false, false, false);
for v in [v3, v5, v6] {
assert_eq!(v, CppVerdict::Pass);
}
}
}