Bug
When a proto oneof contains a field named self, buffa-codegen converts it to PascalCase Self when generating the Rust enum variant — which is a reserved keyword and produces invalid Rust code.
Reproducer: The upstream Temporal API proto contains this definition:
message SetWorkerDeploymentManagerRequest {
oneof new_manager_identity {
string manager_identity = 3;
bool self = 4; // <-- triggers the bug
}
}
buffa-codegen emits:
pub enum NewManagerIdentity {
ManagerIdentity(String),
Self(bool), // ERROR: `Self` is a reserved keyword
}
This causes buffa_codegen::generate() to fail with:
generated code failed to parse as Rust: expected identifier, found keyword `Self`
Root cause
In buffa-codegen, every place that converts a proto field name to a PascalCase enum variant identifier uses format_ident!("{}", to_pascal_case(proto_name)) without checking for reserved keywords. The affected files/lines (v0.3.0):
oneof.rs — collect_variant_info (the enum definition itself)
impl_message.rs — encode/size codegen
message.rs — JSON deserialise codegen
impl_text.rs — text-format encode and decode codegen (two sites)
view.rs — view enum definition and merge codegen (three sites)
make_field_ident already handles this correctly for struct fields (self → self_), but the variant path has no equivalent guard.
Fix
Add a make_variant_ident(proto_name: &str) -> Ident helper (analogous to make_field_ident) that applies keyword escaping after PascalCase conversion:
self / super / Self / crate — append _ (can't be raw identifiers), e.g. Self_
- other keywords — use
r#name
Replace all eight format_ident!("{}", to_pascal_case(...)) call sites with this helper.
Secondary bug (same root cause exposure)
When run() in protoc-gen-buffa returns an error, the error response sets supported_features (which includes FEATURE_SUPPORTS_EDITIONS) but omits minimum_edition / maximum_edition. buf v1.47+ validates this and rejects the response with a misleading error:
plugin protoc-gen-buffa: CodeGeneratorResponse: supported_features: FEATURE_SUPPORTS_EDITIONS specified but no minimum_edition set
This masks the real codegen failure. The fix is to include minimum_edition and maximum_edition in the error-path response in protoc-gen-buffa/src/main.rs.
Bug
When a proto
oneofcontains a field namedself,buffa-codegenconverts it to PascalCaseSelfwhen generating the Rust enum variant — which is a reserved keyword and produces invalid Rust code.Reproducer: The upstream Temporal API proto contains this definition:
buffa-codegenemits:This causes
buffa_codegen::generate()to fail with:Root cause
In
buffa-codegen, every place that converts a proto field name to a PascalCase enum variant identifier usesformat_ident!("{}", to_pascal_case(proto_name))without checking for reserved keywords. The affected files/lines (v0.3.0):oneof.rs—collect_variant_info(the enum definition itself)impl_message.rs— encode/size codegenmessage.rs— JSON deserialise codegenimpl_text.rs— text-format encode and decode codegen (two sites)view.rs— view enum definition and merge codegen (three sites)make_field_identalready handles this correctly for struct fields (self→self_), but the variant path has no equivalent guard.Fix
Add a
make_variant_ident(proto_name: &str) -> Identhelper (analogous tomake_field_ident) that applies keyword escaping after PascalCase conversion:self/super/Self/crate— append_(can't be raw identifiers), e.g.Self_r#nameReplace all eight
format_ident!("{}", to_pascal_case(...))call sites with this helper.Secondary bug (same root cause exposure)
When
run()inprotoc-gen-buffareturns an error, the error response setssupported_features(which includesFEATURE_SUPPORTS_EDITIONS) but omitsminimum_edition/maximum_edition.bufv1.47+ validates this and rejects the response with a misleading error:This masks the real codegen failure. The fix is to include
minimum_editionandmaximum_editionin the error-path response inprotoc-gen-buffa/src/main.rs.