use crate::database::introspection::Enum;
use crate::generators::rust::casing;
pub(super) fn render(item: &Enum) -> String {
let mut taken: Vec<String> = Vec::with_capacity(item.values.len());
let mut rendered = String::new();
for (index, value) in item.values.iter().enumerate() {
let ident = unique(casing::to_pascal(value), &taken);
rendered.push_str(&variant(value, &ident, index == 0));
taken.push(ident);
}
rendered
}
fn unique(candidate: String, taken: &[String]) -> String {
if !taken.contains(&candidate) {
return candidate;
}
(2..)
.map(|index| format!("{candidate}{index}"))
.find(|suffixed| !taken.contains(suffixed))
.expect("an unbounded range always yields an unused identifier")
}
fn variant(value: &str, ident: &str, is_default: bool) -> String {
let default = if is_default { "\t#[default]\n" } else { "" };
if ident == value {
return format!("{default}\t{ident},\n");
}
format!(
"{default}\t#[sqlx(rename = \"{value}\")]\n\t#[serde(rename = \"{value}\")]\n\t{ident},\n"
)
}