pub fn to_snake_case(name: &str) -> String {
let mut result = String::new();
for (i, ch) in name.chars().enumerate() {
if ch.is_uppercase() && i > 0 {
let prev = name.chars().nth(i - 1).unwrap_or('_');
if prev.is_lowercase() || prev.is_ascii_digit() {
result.push('_');
}
}
result.push(
ch.to_lowercase()
.next()
.expect("to_lowercase always yields at least one char"),
);
}
result
}
pub fn c_type_name(prefix: &str, name: &str) -> String {
format!("{prefix}_{}_t", to_snake_case(name))
}
pub fn c_func_name(prefix: &str, name: &str, suffix: &str) -> String {
format!("{prefix}_{}_{suffix}", to_snake_case(name))
}
pub fn c_enum_member(prefix: &str, enum_name: &str, member: &str) -> String {
format!(
"{}_{}_{member}",
prefix.to_uppercase(),
to_snake_case(enum_name).to_uppercase()
)
}
pub fn c_frame_tag_type(prefix: &str, frame_name: &str) -> String {
format!("{prefix}_{}_tag_t", to_snake_case(frame_name))
}
pub fn c_frame_tag_value(prefix: &str, frame_name: &str, variant: &str) -> String {
format!(
"{}_{}_{}",
prefix.to_uppercase(),
to_snake_case(frame_name).to_uppercase(),
to_snake_case(variant).to_uppercase()
)
}
pub fn c_include_guard(prefix: &str) -> String {
format!("{}_H", prefix.to_uppercase())
}