fix(interface): preserve operation item uniqueness
Disambiguate generated argument types when distinct operation names normalize to the same PascalCase form, and add the requested Number round-trip and collision regression coverage.
This commit is contained in:
@@ -112,6 +112,36 @@ fn expand_interface(attribute: TokenStream2, item: ItemTrait) -> syn::Result<Tok
|
||||
operations.push(operation);
|
||||
}
|
||||
|
||||
// PascalCase normalization is convenient for the public generated item,
|
||||
// but distinct Rust names such as `item` and `item_` normalize identically.
|
||||
// Add a stable source-name suffix to every member of a colliding group so
|
||||
// otherwise-valid operations always produce distinct public Rust items.
|
||||
let mut seen_argument_items = HashSet::new();
|
||||
let mut colliding_argument_items = HashSet::new();
|
||||
for operation in &operations {
|
||||
let name = operation.arguments_ident.to_string();
|
||||
if !seen_argument_items.insert(name.clone()) {
|
||||
colliding_argument_items.insert(name);
|
||||
}
|
||||
}
|
||||
for operation in &mut operations {
|
||||
if colliding_argument_items.contains(&operation.arguments_ident.to_string()) {
|
||||
let suffix = operation
|
||||
.name
|
||||
.as_bytes()
|
||||
.iter()
|
||||
.map(|byte| format!("{byte:02x}"))
|
||||
.collect::<String>();
|
||||
operation.arguments_ident = format_ident!(
|
||||
"{}{}ArgumentsN{}",
|
||||
trait_ident,
|
||||
pascal_case(&operation.name),
|
||||
suffix,
|
||||
span = operation.ident.span()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let argument_items = operations.iter().map(argument_item);
|
||||
let operation_declarations = operations.iter().map(operation_declaration);
|
||||
let declaration_collectors = operations.iter().flat_map(operation_collectors);
|
||||
|
||||
Reference in New Issue
Block a user