alex/volcanic
Automated vulkan bindings
BRANCH main
SNAPSHOT Improved loading api and made ready for publish
DOWNLOAD
root codegen src emit declarations.rs
use super::*;
pub(super) fn params(decls: &[Decl]) -> String {
decls
.iter()
.filter(|decl| select::api_matches(decl.api.as_deref()))
.map(|decl| format!("{}: {}", rust_ident(&decl.name), rust_param_type(decl)))
.collect::<Vec<_>>()
.join(", ")
}
pub(super) fn rust_param_type(decl: &Decl) -> String {
if decl.arrays.is_empty() {
return rust_decl_type(decl, false);
}
// C array parameters decay to a pointer to the first element
let mut element = decl.clone();
element.arrays.remove(0);
let pointee_const = decl.pointer_const.is_empty() && decl.base_const;
format!(
"*{} {}",
if pointee_const { "const" } else { "mut" },
rust_decl_type(&element, false)
)
}
pub(super) fn call_args(decls: &[Decl]) -> String {
decls
.iter()
.filter(|decl| select::api_matches(decl.api.as_deref()))
.map(|decl| rust_ident(&decl.name))
.collect::<Vec<_>>()
.join(", ")
}
pub(super) fn rust_decl_type(decl: &Decl, is_return: bool) -> String {
let mut ty = if is_return && decl.base == "void" && decl.pointer_const.is_empty() {
"()".to_string()
} else {
rust_base(&decl.base)
};
for pointee_const in &decl.pointer_const {
ty = format!("*{} {ty}", if *pointee_const { "const" } else { "mut" });
}
for dim in decl.arrays.iter().rev() {
ty = format!("[{ty}; {}]", array_dim(dim));
}
ty
}
pub(super) fn rust_base(base: &str) -> String {
match base {
"void" => "c_void".to_string(),
"char" => "c_char".to_string(),
"float" => "f32".to_string(),
"double" => "f64".to_string(),
"int" => "c_int".to_string(),
"int8_t" => "i8".to_string(),
"uint8_t" => "u8".to_string(),
"int16_t" => "i16".to_string(),
"uint16_t" => "u16".to_string(),
"int32_t" => "i32".to_string(),
"uint32_t" => "u32".to_string(),
"int64_t" => "i64".to_string(),
"uint64_t" => "u64".to_string(),
"size_t" => "usize".to_string(),
other => other.to_string(),
}
}
pub(super) fn array_dim(dim: &str) -> String {
if dim.bytes().all(|b| b.is_ascii_digit()) {
dim.to_string()
} else {
format!("{dim} as usize")
}
}