use std::collections::BTreeMap;
use super::union_types::CollisionStrategy;
use crate::generator::ast::{Documentation, EnumDef, EnumToken, EnumVariantToken, RustType, VariantDef};
#[derive(Clone, Debug)]
pub(crate) struct ValueEnumBuilder {
case_insensitive: bool,
}
impl ValueEnumBuilder {
pub(crate) fn new(case_insensitive: bool) -> Self {
Self { case_insensitive }
}
pub(crate) fn build_enum_from_variants(
&self,
name: &str,
variants: Vec<VariantDef>,
strategy: CollisionStrategy,
docs: Documentation,
) -> RustType {
let (resolved_variants, _) = variants.into_iter().enumerate().fold(
(vec![], BTreeMap::<String, usize>::new()),
|(mut acc, mut seen): (Vec<VariantDef>, BTreeMap<String, usize>), (i, mut variant)| {
let variant_name = variant.name.to_string();
match seen.get(&variant_name).copied() {
Some(idx) if strategy == CollisionStrategy::Deduplicate => {
acc[idx].add_alias(variant.serde_name());
}
Some(_) => {
let unique_name = format!("{variant_name}{i}");
seen.insert(unique_name.clone(), acc.len());
variant.name = EnumVariantToken::from(unique_name);
acc.push(variant);
}
None => {
seen.insert(variant_name, acc.len());
acc.push(variant);
}
}
(acc, seen)
},
);
RustType::Enum(
EnumDef::builder()
.name(EnumToken::from_raw(name))
.docs(docs)
.variants(resolved_variants)
.case_insensitive(self.case_insensitive)
.generate_display(true)
.build(),
)
}
}