use crate::backends::swift::gen_bindings::dto::emit_decoder_init;
use crate::backends::swift::type_map::SwiftMapper;
use crate::core::ir::{DefaultValue, FieldDef, PrimitiveType, TypeRef};
fn decode_body(name: &str, ty: TypeRef, typed_default: DefaultValue) -> String {
let field = FieldDef {
name: name.to_string(),
ty,
typed_default: Some(typed_default),
..Default::default()
};
let mut out = String::new();
emit_decoder_init(&SwiftMapper, &[&field], &mut out);
out
}
#[test]
fn a_named_serde_default_on_a_vec_defers_to_rust_instead_of_decoding_an_empty_array() {
let out = decode_body(
"scheme_allowlist",
TypeRef::Vec(Box::new(TypeRef::String)),
DefaultValue::FunctionCall("default_scheme_allowlist".to_string()),
);
assert!(
!out.contains("?? []"),
"alef never evaluates default_scheme_allowlist(); `?? []` decodes an absent key into an \
empty allow-list that permits nothing:\n{out}"
);
assert!(
out.contains("try container.decode([String].self, forKey: .schemeAllowlist)"),
"an unreadable default must leave the key required so an absent key is a visible \
DecodingError:\n{out}"
);
}
#[test]
fn a_named_serde_default_on_a_map_defers_to_rust_instead_of_decoding_an_empty_dictionary() {
let out = decode_body(
"header_overrides",
TypeRef::Map(Box::new(TypeRef::String), Box::new(TypeRef::String)),
DefaultValue::PublicFunctionCall("sample_crate::Policy::header_overrides".to_string()),
);
assert!(
!out.contains("?? [:]"),
"a resolved function-call default is still a value alef has not read:\n{out}"
);
}
#[test]
fn an_empty_default_still_decodes_to_the_swift_collection_zero() {
let vec_out = decode_body(
"scheme_allowlist",
TypeRef::Vec(Box::new(TypeRef::String)),
DefaultValue::Empty,
);
assert!(
vec_out.contains("?? []"),
"`Empty` is the type's own default and keeps the empty-array fallback:\n{vec_out}"
);
let map_out = decode_body(
"header_overrides",
TypeRef::Map(Box::new(TypeRef::String), Box::new(TypeRef::String)),
DefaultValue::Empty,
);
assert!(
map_out.contains("?? [:]"),
"`Empty` keeps the empty-dictionary fallback:\n{map_out}"
);
let scalar_out = decode_body(
"redirect_limit",
TypeRef::Primitive(PrimitiveType::U32),
DefaultValue::Empty,
);
assert!(
scalar_out.contains("?? 0"),
"`Empty` keeps the scalar zero fallback:\n{scalar_out}"
);
}