//! Swift value descriptor generation.
//!
//! These descriptors are process-local metadata for a Swift codec/JIT backend.
//! They describe the concrete Swift value layout generated by this codegen pass;
//! postcard bytes remain the transport boundary.
use std::collections::{HashMap, HashSet};
use facet_core::{Field, ScalarType, Shape};
use vox_types::{
EnumInfo, MethodDescriptor, ShapeKind, StructInfo, TypeRef, VariantKind, classify_shape,
classify_variant, extract_schemas, is_bytes,
};
use super::types::{swift_field_name, swift_type_base};
#[derive(Clone, Copy)]
struct DescriptorNode {
shape: &'static Shape,
}
/// Generate a Swift descriptor registry for named types and their dependencies.
pub fn generate_value_descriptors(
registry_name: &str,
named_types: &[(String, &'static Shape)],
) -> String {
generate_value_descriptors_inner(registry_name, named_types, &[])
}
/// Generate a Swift descriptor registry plus per-method local value roots.
pub fn generate_service_value_descriptors(
registry_name: &str,
named_types: &[(String, &'static Shape)],
methods: &[&MethodDescriptor],
) -> String {
generate_value_descriptors_inner(registry_name, named_types, methods)
}
fn generate_value_descriptors_inner(
registry_name: &str,
named_types: &[(String, &'static Shape)],
methods: &[&MethodDescriptor],
) -> String {
let mut nodes = Vec::new();
let mut seen = HashSet::new();
for (_, shape) in named_types {
collect_shape(shape, &mut seen, &mut nodes);
}
for method in methods {
collect_shape(method.args_shape, &mut seen, &mut nodes);
collect_shape(method.return_shape, &mut seen, &mut nodes);
}
if nodes.is_empty() {
return String::new();
}
let prefix = swift_ident_fragment(registry_name);
let mut index_by_shape = HashMap::new();
for (index, node) in nodes.iter().enumerate() {
index_by_shape.insert(shape_key(node.shape), index);
}
let mut out = String::new();
out.push_str("// MARK: - Swift Value Descriptors\n\n");
for (index, node) in nodes.iter().enumerate() {
out.push_str(&generate_value_witnesses(&prefix, index, node.shape));
if is_named_enum(node.shape) {
out.push_str(&generate_enum_witnesses(&prefix, index, node.shape));
}
}
out.push_str(&format!(
"nonisolated(unsafe) public let {prefix}_swift_value_descriptors: VoxSwiftDescriptorRegistry = {{\n"
));
out.push_str(" let registry = VoxSwiftDescriptorRegistry()\n");
for index in 0..nodes.len() {
out.push_str(&format!(
" let {} = registry.reserveDescriptor()\n",
desc_var(index)
));
}
out.push('\n');
for (index, node) in nodes.iter().enumerate() {
out.push_str(&generate_descriptor_definition(
&prefix,
index,
node.shape,
&index_by_shape,
));
out.push('\n');
}
for method in methods {
let args_root = index_by_shape[&shape_key(method.args_shape)];
let response_root = index_by_shape[&shape_key(method.return_shape)];
out.push_str(&format!(
" registry.defineMethod(methodId: {}, argsRoot: UnsafePointer({}), responseRoot: UnsafePointer({}))\n",
swift_hex(crate::method_id(method)),
desc_var(args_root),
desc_var(response_root)
));
}
if !methods.is_empty() {
out.push('\n');
}
out.push_str(" return registry\n");
out.push_str("}()\n\n");
out.push_str(&format!(
"nonisolated(unsafe) public let {prefix}_swift_value_descriptor_registry: [UInt64: UnsafePointer<VoxSwiftTypeDescriptor>] = {prefix}_swift_value_descriptors.bySchemaId\n\n"
));
if !methods.is_empty() {
out.push_str(&format!(
"nonisolated(unsafe) public let {prefix}_swift_method_value_descriptors: [UInt64: VoxSwiftMethodValueDescriptorInfo] = {prefix}_swift_value_descriptors.methodById\n\n"
));
}
out
}
fn collect_shape(
shape: &'static Shape,
seen: &mut HashSet<usize>,
nodes: &mut Vec<DescriptorNode>,
) {
if !seen.insert(shape_key(shape)) {
return;
}
nodes.push(DescriptorNode { shape });
if is_bytes(shape) {
return;
}
match classify_shape(shape) {
ShapeKind::List { element }
| ShapeKind::Slice { element }
| ShapeKind::Array { element, .. }
| ShapeKind::Set { element }
| ShapeKind::Option { inner: element }
| ShapeKind::Tx { inner: element }
| ShapeKind::Rx { inner: element } => collect_shape(element, seen, nodes),
ShapeKind::Map { key, value } => {
collect_shape(key, seen, nodes);
collect_shape(value, seen, nodes);
}
ShapeKind::Struct(StructInfo { fields, .. }) | ShapeKind::TupleStruct { fields } => {
for field in fields {
collect_shape(field.shape(), seen, nodes);
}
}
ShapeKind::Enum(EnumInfo { variants, .. }) => {
for variant in variants {
for field in variant_fields(variant) {
collect_shape(field.shape(), seen, nodes);
}
}
}
ShapeKind::Tuple { elements } => {
for element in elements {
collect_shape(element.shape, seen, nodes);
}
}
ShapeKind::Pointer { pointee } => collect_shape(pointee, seen, nodes),
ShapeKind::Result { ok, err } => {
collect_shape(ok, seen, nodes);
collect_shape(err, seen, nodes);
}
ShapeKind::Scalar(_) | ShapeKind::Opaque => {}
}
}
fn generate_value_witnesses(prefix: &str, index: usize, shape: &'static Shape) -> String {
let ty = swift_type_base(shape);
let witness = witness_prefix(prefix, index);
format!(
"nonisolated private func {witness}_destroy(_ value: UnsafeMutableRawPointer?, _ context: UnsafeRawPointer?) {{\n guard let value else {{ return }}\n value.assumingMemoryBound(to: {ty}.self).deinitialize(count: 1)\n}}\n\nnonisolated private func {witness}_copyInit(_ dst: UnsafeMutableRawPointer?, _ src: UnsafeRawPointer?, _ context: UnsafeRawPointer?) -> VoxSwiftStatus {{\n guard let dst, let src else {{ return VoxSwiftStatusBadABI }}\n dst.assumingMemoryBound(to: {ty}.self).initialize(to: src.assumingMemoryBound(to: {ty}.self).pointee)\n return VoxSwiftStatusOK\n}}\n\nnonisolated private func {witness}_takeInit(_ dst: UnsafeMutableRawPointer?, _ src: UnsafeMutableRawPointer?, _ context: UnsafeRawPointer?) -> VoxSwiftStatus {{\n guard let dst, let src else {{ return VoxSwiftStatusBadABI }}\n let srcTyped = src.assumingMemoryBound(to: {ty}.self)\n dst.assumingMemoryBound(to: {ty}.self).initialize(to: srcTyped.pointee)\n srcTyped.deinitialize(count: 1)\n return VoxSwiftStatusOK\n}}\n\n"
)
}
fn generate_enum_witnesses(prefix: &str, index: usize, shape: &'static Shape) -> String {
let ShapeKind::Enum(EnumInfo {
name: Some(name),
variants,
}) = classify_shape(shape)
else {
return String::new();
};
let witness = witness_prefix(prefix, index);
let mut out = String::new();
out.push_str(&format!(
"nonisolated private func {witness}_tag(_ value: UnsafeRawPointer?, _ context: UnsafeRawPointer?) -> UInt32 {{\n"
));
out.push_str(" guard let value else { return UInt32.max }\n");
out.push_str(&format!(
" switch value.assumingMemoryBound(to: {name}.self).pointee {{\n"
));
for (variant_index, variant) in variants.iter().enumerate() {
out.push_str(&format!(
" case {}:\n return UInt32({variant_index})\n",
enum_tag_pattern(variant)
));
}
out.push_str(" }\n");
out.push_str("}\n\n");
out.push_str(&format!(
"nonisolated private func {witness}_project(_ value: UnsafeRawPointer?, _ variantIndex: UInt32, _ visitorContext: UnsafeMutableRawPointer?, _ visitor: VoxSwiftEnumFieldVisitorFn?, _ context: UnsafeRawPointer?) -> VoxSwiftStatus {{\n"
));
let needs_visitor = variants
.iter()
.any(|variant| !variant_fields(variant).is_empty());
if needs_visitor {
out.push_str(" guard let value, let visitor else { return VoxSwiftStatusBadABI }\n");
} else {
out.push_str(" guard let value else { return VoxSwiftStatusBadABI }\n");
}
out.push_str(&format!(
" switch value.assumingMemoryBound(to: {name}.self).pointee {{\n"
));
for (variant_index, variant) in variants.iter().enumerate() {
let fields = variant_fields(variant);
out.push_str(&format!(" case {}:\n", enum_project_pattern(variant)));
out.push_str(&format!(
" guard variantIndex == UInt32({variant_index}) else {{ return VoxSwiftStatusBadABI }}\n"
));
out.push_str(&project_visitor_calls(&fields, 8));
}
out.push_str(" }\n");
out.push_str("}\n\n");
out.push_str(&format!(
"nonisolated private func {witness}_inject(_ dst: UnsafeMutableRawPointer?, _ variantIndex: UInt32, _ fieldValues: UnsafePointer<UnsafeRawPointer?>?, _ fieldCount: Int, _ context: UnsafeRawPointer?) -> VoxSwiftStatus {{\n"
));
out.push_str(" guard let dst else { return VoxSwiftStatusBadABI }\n");
out.push_str(" switch variantIndex {\n");
for (variant_index, variant) in variants.iter().enumerate() {
let fields = variant_fields(variant);
out.push_str(&format!(" case UInt32({variant_index}):\n"));
out.push_str(&format!(
" guard fieldCount == {} else {{ return VoxSwiftStatusBadABI }}\n",
fields.len()
));
if !fields.is_empty() {
out.push_str(" guard let fieldValues else { return VoxSwiftStatusBadABI }\n");
}
for (field_index, field) in fields.iter().enumerate() {
let ty = swift_type_base(field.shape());
out.push_str(&format!(
" guard let f{field_index}Ptr = fieldValues[{field_index}] else {{ return VoxSwiftStatusBadABI }}\n"
));
out.push_str(&format!(
" let f{field_index} = f{field_index}Ptr.assumingMemoryBound(to: {ty}.self).pointee\n"
));
}
out.push_str(&format!(
" dst.assumingMemoryBound(to: {name}.self).initialize(to: {})\n",
enum_construct_expr(variant)
));
out.push_str(" return VoxSwiftStatusOK\n");
}
out.push_str(" default:\n");
out.push_str(" return VoxSwiftStatusBadABI\n");
out.push_str(" }\n");
out.push_str("}\n\n");
out
}
fn generate_descriptor_definition(
prefix: &str,
index: usize,
shape: &'static Shape,
index_by_shape: &HashMap<usize, usize>,
) -> String {
let var = desc_var(index);
let fields_var = format!("{var}Fields");
let variants_var = format!("{var}Variants");
let type_args_var = format!("{var}TypeArgs");
let mut out = String::new();
let field_descriptors = descriptor_fields(shape, index_by_shape);
if !field_descriptors.is_empty() {
out.push_str(&format!(
" let {fields_var} = registry.allocateFields([\n{}\n ])\n",
field_descriptors.join(",\n")
));
}
let type_args = descriptor_type_args(shape, index_by_shape);
if !type_args.is_empty() {
out.push_str(&format!(
" let {type_args_var} = registry.allocateTypeArgs([{}])\n",
type_args
.iter()
.map(|idx| format!("UnsafePointer({})", desc_var(*idx)))
.collect::<Vec<_>>()
.join(", ")
));
}
let variant_descriptors = descriptor_variants(index, shape, index_by_shape);
if !variant_descriptors.is_empty() {
out.push_str(&variant_descriptors.join(""));
out.push_str(&format!(
" let {variants_var} = registry.allocateVariants([\n{}\n ])\n",
descriptor_variant_array_entries(index, shape).join(",\n")
));
}
let fields_expr = if field_descriptors.is_empty() {
"nil".to_string()
} else {
fields_var
};
let field_count = field_descriptors.len();
let variants_expr = if variant_descriptors.is_empty() {
"nil".to_string()
} else {
variants_var
};
let variant_count = descriptor_variant_count(shape);
let type_args_expr = if type_args.is_empty() {
"nil".to_string()
} else {
type_args_var
};
let type_arg_count = type_args.len();
let witness = witness_prefix(prefix, index);
let enum_witnesses = if is_named_enum(shape) {
format!(
"VoxSwiftEnumWitnesses(tag: {witness}_tag, project: {witness}_project, inject: {witness}_inject)"
)
} else {
"VoxSwiftEnumWitnesses()".to_string()
};
out.push_str(&format!(
" _ = registry.defineDescriptor(\n {var},\n as: VoxSwiftTypeDescriptor.concrete(\n of: {}.self,\n kind: {},\n primitiveKind: {},\n flags: {},\n schemaId: {},\n typeArgs: {type_args_expr},\n typeArgCount: {type_arg_count},\n fields: {fields_expr},\n fieldCount: {field_count},\n variants: {variants_expr},\n variantCount: {variant_count},\n witnesses: VoxSwiftValueWitnesses(destroy: {witness}_destroy, copyInit: {witness}_copyInit, takeInit: {witness}_takeInit),\n enumWitnesses: {enum_witnesses}\n )\n )\n",
swift_type_base(shape),
descriptor_kind(shape),
descriptor_primitive_kind(shape),
descriptor_flags(shape),
swift_hex(root_schema_id(shape).0),
));
out
}
fn descriptor_fields(shape: &'static Shape, index_by_shape: &HashMap<usize, usize>) -> Vec<String> {
match classify_shape(shape) {
ShapeKind::Struct(StructInfo {
name: Some(type_name),
fields,
..
}) => fields
.iter()
.map(|field| {
let child_index = index_by_shape[&shape_key(field.shape())];
format!(
" VoxSwiftFieldDescriptor(name: .staticString(\"{}\"), schemaId: {}, type: UnsafePointer({}), offset: MemoryLayout<{type_name}>.offset(of: \\{type_name}.{})!)",
escape_swift_string(field.name),
swift_hex(root_schema_id(field.shape()).0),
desc_var(child_index),
swift_field_name(field.name)
)
})
.collect(),
ShapeKind::TupleStruct { fields } => fields
.iter()
.enumerate()
.map(|(field_index, field)| tuple_field_descriptor(field_index, field, index_by_shape))
.collect(),
_ => Vec::new(),
}
}
fn descriptor_type_args(
shape: &'static Shape,
index_by_shape: &HashMap<usize, usize>,
) -> Vec<usize> {
let mut args = Vec::new();
if is_bytes(shape) {
return args;
}
match classify_shape(shape) {
ShapeKind::List { element }
| ShapeKind::Slice { element }
| ShapeKind::Array { element, .. }
| ShapeKind::Set { element }
| ShapeKind::Option { inner: element }
| ShapeKind::Tx { inner: element }
| ShapeKind::Rx { inner: element } => {
args.push(index_by_shape[&shape_key(element)]);
}
ShapeKind::Map { key, value }
| ShapeKind::Result {
ok: key,
err: value,
} => {
args.push(index_by_shape[&shape_key(key)]);
args.push(index_by_shape[&shape_key(value)]);
}
ShapeKind::Tuple { elements } => {
for element in elements {
args.push(index_by_shape[&shape_key(element.shape)]);
}
}
ShapeKind::Pointer { pointee } => {
args.push(index_by_shape[&shape_key(pointee)]);
}
_ => {}
}
args
}
fn descriptor_variants(
descriptor_index: usize,
shape: &'static Shape,
index_by_shape: &HashMap<usize, usize>,
) -> Vec<String> {
let ShapeKind::Enum(EnumInfo {
name: Some(_),
variants,
}) = classify_shape(shape)
else {
return Vec::new();
};
variants
.iter()
.enumerate()
.map(|(variant_index, variant)| {
let fields = variant_fields(variant);
if fields.is_empty() {
return String::new();
}
let entries = fields
.iter()
.enumerate()
.map(|(field_index, field)| {
tuple_field_descriptor(field_index, field, index_by_shape)
})
.collect::<Vec<_>>()
.join(",\n");
format!(
" let {} = registry.allocateFields([\n{}\n ])\n",
variant_fields_var(descriptor_index, variant_index),
entries
)
})
.collect()
}
fn descriptor_variant_array_entries(descriptor_index: usize, shape: &'static Shape) -> Vec<String> {
let ShapeKind::Enum(EnumInfo {
name: Some(_),
variants,
}) = classify_shape(shape)
else {
return Vec::new();
};
variants
.iter()
.enumerate()
.map(|(variant_index, variant)| {
let fields = variant_fields(variant);
let fields_expr = if fields.is_empty() {
"nil".to_string()
} else {
variant_fields_var(descriptor_index, variant_index)
};
format!(
" VoxSwiftVariantDescriptor(name: .staticString(\"{}\"), index: UInt32({variant_index}), fields: {fields_expr}, fieldCount: {})",
escape_swift_string(variant.name),
fields.len()
)
})
.collect()
}
fn descriptor_variant_count(shape: &'static Shape) -> usize {
match classify_shape(shape) {
ShapeKind::Enum(EnumInfo {
name: Some(_),
variants,
}) => variants.len(),
_ => 0,
}
}
fn tuple_field_descriptor(
field_index: usize,
field: &Field,
index_by_shape: &HashMap<usize, usize>,
) -> String {
let child_index = index_by_shape[&shape_key(field.shape())];
let name = if field.name.is_empty() {
field_index.to_string()
} else {
field.name.to_string()
};
format!(
" VoxSwiftFieldDescriptor(name: .staticString(\"{}\"), schemaId: {}, type: UnsafePointer({}), offset: 0)",
escape_swift_string(&name),
swift_hex(root_schema_id(field.shape()).0),
desc_var(child_index)
)
}
fn descriptor_kind(shape: &'static Shape) -> &'static str {
if is_bytes(shape) {
return "VoxSwiftTypeKindBytes";
}
match classify_shape(shape) {
ShapeKind::Scalar(ScalarType::String | ScalarType::Str | ScalarType::CowStr) => {
"VoxSwiftTypeKindString"
}
ShapeKind::Scalar(_) => "VoxSwiftTypeKindPrimitive",
ShapeKind::Struct(_) | ShapeKind::TupleStruct { .. } => "VoxSwiftTypeKindStruct",
ShapeKind::Enum(EnumInfo { name: Some(_), .. }) => "VoxSwiftTypeKindEnum",
ShapeKind::Enum(EnumInfo { name: None, .. }) => "VoxSwiftTypeKindOpaque",
ShapeKind::Tuple { .. } => "VoxSwiftTypeKindTuple",
ShapeKind::List { .. } | ShapeKind::Slice { .. } | ShapeKind::Set { .. } => {
"VoxSwiftTypeKindList"
}
ShapeKind::Map { .. } => "VoxSwiftTypeKindMap",
ShapeKind::Array { .. } => "VoxSwiftTypeKindArray",
ShapeKind::Option { .. } => "VoxSwiftTypeKindOption",
ShapeKind::Tx { .. } | ShapeKind::Rx { .. } => "VoxSwiftTypeKindChannel",
ShapeKind::Pointer { .. } | ShapeKind::Result { .. } | ShapeKind::Opaque => {
"VoxSwiftTypeKindOpaque"
}
}
}
fn descriptor_primitive_kind(shape: &'static Shape) -> &'static str {
match classify_shape(shape) {
ShapeKind::Scalar(ScalarType::Unit) => "VoxSwiftPrimitiveUnit",
ShapeKind::Scalar(ScalarType::Bool) => "VoxSwiftPrimitiveBool",
ShapeKind::Scalar(ScalarType::U8) => "VoxSwiftPrimitiveU8",
ShapeKind::Scalar(ScalarType::U16) => "VoxSwiftPrimitiveU16",
ShapeKind::Scalar(ScalarType::U32) => "VoxSwiftPrimitiveU32",
ShapeKind::Scalar(ScalarType::U64 | ScalarType::USize) => "VoxSwiftPrimitiveU64",
ShapeKind::Scalar(ScalarType::I8) => "VoxSwiftPrimitiveI8",
ShapeKind::Scalar(ScalarType::I16) => "VoxSwiftPrimitiveI16",
ShapeKind::Scalar(ScalarType::I32) => "VoxSwiftPrimitiveI32",
ShapeKind::Scalar(ScalarType::I64 | ScalarType::ISize) => "VoxSwiftPrimitiveI64",
ShapeKind::Scalar(ScalarType::F32) => "VoxSwiftPrimitiveF32",
ShapeKind::Scalar(ScalarType::F64) => "VoxSwiftPrimitiveF64",
_ => "VoxSwiftPrimitiveUnit",
}
}
fn descriptor_flags(shape: &'static Shape) -> &'static str {
match classify_shape(shape) {
ShapeKind::Scalar(
ScalarType::Unit
| ScalarType::Bool
| ScalarType::U8
| ScalarType::U16
| ScalarType::U32
| ScalarType::U64
| ScalarType::USize
| ScalarType::I8
| ScalarType::I16
| ScalarType::I32
| ScalarType::I64
| ScalarType::ISize
| ScalarType::F32
| ScalarType::F64,
) => {
"VoxSwiftTypeFlagTrivial | VoxSwiftTypeFlagBitwiseMovable | VoxSwiftTypeFlagFixedLayout"
}
ShapeKind::Struct(_) | ShapeKind::Enum(_) | ShapeKind::TupleStruct { .. } => {
"VoxSwiftTypeFlagFixedLayout"
}
_ => "0",
}
}
fn is_named_enum(shape: &'static Shape) -> bool {
matches!(
classify_shape(shape),
ShapeKind::Enum(EnumInfo { name: Some(_), .. })
)
}
fn variant_fields(variant: &facet_core::Variant) -> Vec<&Field> {
match classify_variant(variant) {
VariantKind::Unit => Vec::new(),
VariantKind::Newtype { .. } | VariantKind::Tuple { .. } | VariantKind::Struct { .. } => {
variant.data.fields.iter().collect()
}
}
}
fn enum_tag_pattern(variant: &facet_core::Variant) -> String {
let name = swift_field_name(variant.name);
match classify_variant(variant) {
VariantKind::Unit => format!(".{name}"),
VariantKind::Newtype { .. } => format!(".{name}(_)"),
VariantKind::Tuple { fields } => {
format!(".{name}({})", vec!["_"; fields.len()].join(", "))
}
VariantKind::Struct { fields } => {
let labels = fields
.iter()
.map(|f| format!("{}: _", swift_field_name(f.name)))
.collect::<Vec<_>>()
.join(", ");
format!(".{name}({labels})")
}
}
}
fn enum_project_pattern(variant: &facet_core::Variant) -> String {
let name = swift_field_name(variant.name);
match classify_variant(variant) {
VariantKind::Unit => format!(".{name}"),
VariantKind::Newtype { .. } => format!(".{name}(let f0)"),
VariantKind::Tuple { fields } => {
let bindings = (0..fields.len())
.map(|i| format!("let f{i}"))
.collect::<Vec<_>>()
.join(", ");
format!(".{name}({bindings})")
}
VariantKind::Struct { fields } => {
let bindings = fields
.iter()
.enumerate()
.map(|(i, f)| format!("{}: let f{i}", swift_field_name(f.name)))
.collect::<Vec<_>>()
.join(", ");
format!(".{name}({bindings})")
}
}
}
fn enum_construct_expr(variant: &facet_core::Variant) -> String {
let name = swift_field_name(variant.name);
match classify_variant(variant) {
VariantKind::Unit => format!(".{name}"),
VariantKind::Newtype { .. } => format!(".{name}(f0)"),
VariantKind::Tuple { fields } => {
let args = (0..fields.len())
.map(|i| format!("f{i}"))
.collect::<Vec<_>>()
.join(", ");
format!(".{name}({args})")
}
VariantKind::Struct { fields } => {
let args = fields
.iter()
.enumerate()
.map(|(i, f)| format!("{}: f{i}", swift_field_name(f.name)))
.collect::<Vec<_>>()
.join(", ");
format!(".{name}({args})")
}
}
}
fn project_visitor_calls(fields: &[&Field], indent: usize) -> String {
if fields.is_empty() {
return format!("{}return VoxSwiftStatusOK\n", " ".repeat(indent));
}
fn rec(field_index: usize, field_count: usize, indent: usize) -> String {
let pad = " ".repeat(indent);
let mut out = String::new();
out.push_str(&format!(
"{pad}return withUnsafePointer(to: f{field_index}) {{ f{field_index}Ptr in\n"
));
out.push_str(&format!(
"{pad} let status = visitor(visitorContext, {field_index}, UnsafeRawPointer(f{field_index}Ptr))\n"
));
out.push_str(&format!(
"{pad} guard status == VoxSwiftStatusOK else {{ return status }}\n"
));
if field_index + 1 == field_count {
out.push_str(&format!("{pad} return VoxSwiftStatusOK\n"));
} else {
out.push_str(&rec(field_index + 1, field_count, indent + 4));
}
out.push_str(&format!("{pad}}}\n"));
out
}
rec(0, fields.len(), indent)
}
fn root_schema_id(shape: &'static Shape) -> vox_types::SchemaHash {
let extracted = extract_schemas(shape).expect("schema extraction for Swift value descriptor");
match extracted.root {
TypeRef::Concrete { type_id, .. } => type_id,
TypeRef::Var { .. } => panic!("Swift value descriptor root cannot be a type variable"),
}
}
fn desc_var(index: usize) -> String {
format!("d{index}")
}
fn variant_fields_var(descriptor_index: usize, variant_index: usize) -> String {
format!("d{descriptor_index}Variant{variant_index}Fields")
}
fn witness_prefix(prefix: &str, index: usize) -> String {
format!("{prefix}_swift_value_desc_{index}")
}
fn shape_key(shape: &'static Shape) -> usize {
shape as *const Shape as usize
}
fn swift_ident_fragment(input: &str) -> String {
let mut out = String::new();
for ch in input.chars() {
if ch.is_ascii_alphanumeric() {
out.push(ch);
} else {
out.push('_');
}
}
if out
.chars()
.next()
.map(|ch| ch.is_ascii_digit())
.unwrap_or(true)
{
out.insert(0, '_');
}
out
}
fn swift_hex(value: u64) -> String {
format!("0x{value:016x}")
}
fn escape_swift_string(value: &str) -> String {
value.replace('\\', "\\\\").replace('"', "\\\"")
}