use crate::backends::ffi::type_map::result_presence_companion_exists;
use crate::core::config::Language;
use crate::core::ir::{PrimitiveType, ReceiverKind, TypeRef};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum PresenceStance {
ConsumesCompanion,
ConsumesCabiNotYetWired,
NativeOptional,
NoHostReturnSurface,
}
const fn presence_channel_stance(language: Language) -> PresenceStance {
match language {
Language::Go | Language::Java => PresenceStance::ConsumesCompanion,
Language::Kotlin => PresenceStance::ConsumesCompanion,
Language::Csharp | Language::Zig | Language::Dart => PresenceStance::ConsumesCabiNotYetWired,
Language::Python | Language::Node | Language::Ruby | Language::Php | Language::Elixir | Language::R => {
PresenceStance::NativeOptional
}
Language::Wasm | Language::Gleam | Language::Swift => PresenceStance::NativeOptional,
Language::KotlinAndroid | Language::Jni => PresenceStance::NativeOptional,
Language::Ffi | Language::Rust | Language::C => PresenceStance::NoHostReturnSurface,
}
}
#[test]
fn every_language_states_a_presence_stance() {
for language in Language::ALL {
let _ = presence_channel_stance(language);
}
assert_eq!(
Language::ALL.len(),
20,
"a Language variant was added or removed; give it a presence stance above"
);
}
#[test]
fn the_unwired_c_abi_backends_are_exactly_the_known_gaps() {
let unwired: Vec<Language> = Language::ALL
.into_iter()
.filter(|language| presence_channel_stance(*language) == PresenceStance::ConsumesCabiNotYetWired)
.collect();
assert_eq!(
unwired,
vec![Language::Csharp, Language::Dart, Language::Zig],
"the set of C-ABI backends still missing the presence companion changed"
);
}
#[test]
fn the_companion_covers_scalar_optionals_except_on_an_owned_receiver() {
let scalar_option = TypeRef::Optional(Box::new(TypeRef::Primitive(PrimitiveType::I64)));
assert!(result_presence_companion_exists(&scalar_option, None));
assert!(result_presence_companion_exists(
&scalar_option,
Some(&ReceiverKind::Ref)
));
assert!(result_presence_companion_exists(
&scalar_option,
Some(&ReceiverKind::RefMut)
));
assert!(
!result_presence_companion_exists(&scalar_option, Some(&ReceiverKind::Owned)),
"an owned receiver's first call consumes the handle, so the companion cannot re-invoke it"
);
assert!(
!result_presence_companion_exists(&TypeRef::Optional(Box::new(TypeRef::String)), None),
"`Option<String>` already carries a real null pointer and needs no companion"
);
assert!(
!result_presence_companion_exists(&TypeRef::Primitive(PrimitiveType::I64), None),
"a non-optional return has no absence to report"
);
}