alex/volcanic
Automated vulkan bindings
BRANCH main
SNAPSHOT Improved loading api and made ready for publish
DOWNLOAD
root codegen src emit enums.rs
use super::*;
pub(super) fn rust_enum_infos(
vk: &Registry,
video: &Registry,
modules: &[EmitModule],
enum_widths: &IndexMap<String, &'static str>,
bit_enums_to_flags: &IndexMap<String, String>,
) -> IndexMap<String, RustEnumInfo> {
let groups: IndexSet<_> = video
.enum_groups
.iter()
.chain(&vk.enum_groups)
.filter(|group| group.kind == "enum")
.filter_map(|group| group.name.as_deref())
.filter(|name| !bit_enums_to_flags.contains_key(*name))
.collect();
let entries: IndexMap<_, _> = modules
.iter()
.flat_map(|module| module.enums.values())
.map(|resolved| (resolved.entry.name.as_str(), resolved))
.collect();
let mut infos = IndexMap::new();
for module in modules {
for resolved in module.enums.values() {
let Some(group) = resolved
.group_name
.as_deref()
.filter(|name| groups.contains(name))
else {
continue;
};
if !select::api_matches(resolved.entry.api.as_deref()) {
continue;
}
let value = enum_value(resolved, &entries, enum_widths);
insert_enum_constant(
&mut infos,
group,
&enum_variant_name(group, &resolved.entry.name),
value,
&resolved.condition,
);
}
}
infos
}
pub(super) fn enum_value<'a>(
mut resolved: &'a ResolvedEnum,
entries: &IndexMap<&str, &'a ResolvedEnum>,
widths: &IndexMap<String, &'static str>,
) -> String {
for _ in 0..=entries.len() {
let Some(alias) = &resolved.entry.alias else {
return const_value_from_widths(
widths,
&resolved.entry,
resolved.group_name.as_deref(),
resolved.extension_number,
);
};
resolved = entries
.get(alias.as_str())
.unwrap_or_else(|| panic!("unknown enum alias target {alias}"));
}
panic!("cyclic enum alias involving {}", resolved.entry.name);
}
pub(super) fn insert_enum_constant(
infos: &mut IndexMap<String, RustEnumInfo>,
group: &str,
name: &str,
value: String,
condition: &select::FeatureExpr,
) {
let info = infos
.entry(group.to_string())
.or_insert_with(|| RustEnumInfo {
constants: IndexMap::new(),
});
if let Some(existing) = info.constants.get_mut(name) {
assert_eq!(
existing.value, value,
"conflicting values for {group}::{name}"
);
existing.condition =
select::FeatureExpr::any([existing.condition.clone(), condition.clone()]);
} else {
info.constants.insert(
name.to_string(),
EnumConstant {
value,
condition: condition.clone(),
},
);
}
}