v0.5.0
protovalidate-buffa v0.5.0
protovalidate-buffa v0.5.0 lands three important correctness fixes that make the codegen plugin robust across real-world proto schemas: keyword-named fields now produce valid Rust instead of panicking at generation time, the optional Connect integration no longer drags in streaming and compression crates you never asked for, and the whole workspace has been updated to the buffa 0.7 line. The 100% conformance score — 2872 / 2872 cases across proto2, proto3, and editions 2023 — remains intact throughout.
🐛 Bug Fixes
Keyword-named fields and oneofs no longer break codegen
The plugin was building field accessors (self.<field>) directly from raw proto names. Any field or oneof whose name is a Rust keyword caused one of three failure modes:
format_ident!("type")emits the raw invalid tokenself.type—syn/prettypleaserefuse to parse it.parse_str::<Ident>("type")returnsErrand fails the render pipeline.- Keywords that can't be raw identifiers (
self,super,crate,Self) caused an outrightIdent::newpanic at codegen time.
The fix routes every proto-name-to-ident conversion through a shared field_ident helper that delegates to buffa_codegen::idents::make_field_ident — the same function buffa itself uses when naming struct fields. Emitted accessors now match the generated message types by construction:
// proto
message Request {
string type = 1 [(buf.validate.field).string.min_len = 1];
string self = 2 [(buf.validate.field).string.min_len = 1];
}// generated (before this fix: compile error / panic)
impl Validate for Request {
fn validate(&self) -> Result<(), ValidationError> {
// raw-able keyword → r#type
if self.r#type.len() < 1 { /* ... */ }
// non-raw-able keyword → suffixed
if self.self_.len() < 1 { /* ... */ }
Ok(())
}
}Regression tests covering keyword fields, keyword-named oneofs, and CEL rules on keyword-named fields are now part of the plugin's integration test suite.
This is a breaking change if you were working around the bug by renaming proto fields — you can remove those workarounds now.
Connect feature no longer pulls in streaming and compression crates
The optional connect feature only ever needed ConnectError and ErrorCode from connectrpc. By default, connectrpc previously enabled its streaming and compression feature flags, which added async-compression and related transitive dependencies to your build even when you just wanted req.validate()? → InvalidArgument. Those are now gone. Enabling the connect feature is leaner than it used to be.
⚡ Improvements
buffa 0.7
The workspace — runtime, macros, protos, plugin, and conformance harness — is now on the buffa 0.7 line. connectrpc has been moved to its matching 0.7 release to keep the transitive dependency graph consistent.
Conformance
2872 / 2872 (100%) against the upstream protovalidate-conformance suite, covering proto2, proto3, and editions 2023. Every rule family in the standard-rules catalogue and predefined-rules support is covered.
Error handling reminder
Match on the typed ValidationError fields, not on rule_id prefixes:
match req.validate() {
Ok(()) => { /* proceed */ }
Err(e) if e.compile_error.is_some() => {
// Schema-level mismatch caught at codegen time — this is a bug
// in your proto annotations or plugin version. Log and panic in dev.
panic!("protovalidate compile error: {}", e.compile_error.unwrap());
}
Err(e) if e.runtime_error.is_some() => {
// Rule precondition failed at runtime (e.g. bytes.pattern on non-UTF-8).
return Err(e.into_connect_error());
}
Err(e) => {
// The common case: one or more field violations.
return Err(e.into_connect_error()); // → InvalidArgument
}
}Installation
Library consumers — add to Cargo.toml:
protovalidate-buffa = "0.5.0"Codegen plugin — install from source:
cargo install \
--git https://github.com/mathematic-inc/protovalidate-buffa \
--tag v0.5.0 \
protoc-gen-protovalidate-buffaThen wire it into your buf.gen.yaml:
plugins:
- local: protoc-gen-protovalidate-buffa
out: gen/protovalidate
strategy: all