Skip to content

protovalidate-buffa-protos-v0.5.0

Choose a tag to compare

@jrandolf jrandolf released this 28 Jun 01:22
d8d61e6

protovalidate-buffa-protos v0.5.0

This release ships three targeted fixes that make the codegen plugin more
robust in real-world proto schemas: proto fields and oneofs named with Rust
keywords now generate valid code instead of panicking, the connect feature
pulls in substantially fewer transitive dependencies, and the whole workspace
moves to the buffa 0.7 line. The 100% conformance record stands —
2872 / 2872 cases across proto2, proto3, and editions 2023 — and now the
plugin can handle whatever names your protos throw at it.


🐛 Bug Fixes

Rust keyword field and oneof names no longer break codegen

The plugin previously built field accessors (self.<field>) directly from raw
proto names. Any field or oneof named with a Rust keyword — type, match,
use, or even self — caused format_ident! to emit invalid syntax,
parse_str::<Ident> to return an error, or Ident::new to panic outright.

All name-to-ident conversions in the emitter now route through a shared
field_ident helper that delegates to buffa_codegen::idents::make_field_ident
— the exact same function buffa uses when naming struct fields. This guarantees
that generated accessors always match the buffa-generated struct layout, even
on keyword names:

// These used to generate broken Rust. Now they work.
message FilterRequest {
  string type   = 1 [(buf.validate.field).string.min_len = 1];
  string match  = 2 [(buf.validate.field).string.min_len = 1];
}

Generated accessors now emit self.r#type and self.r#match (or the
_-suffix form for the rare non-raw-able keywords), matching the buffa struct
fields exactly. A regression test suite for the full emit::render pipeline
on keyword names is included.

connect feature no longer pulls streaming and compression dependencies

The optional Connect integration only needs ConnectError and ErrorCode.
connectrpc's default features were previously enabled, which dragged in
streaming and compression transitive dependencies unconditionally whenever the
connect feature was active.

connectrpc is now declared with default-features = false, so enabling
connect brings in only what the validation→Connect-error mapping actually
uses. If you match on ValidationError in a Connect handler, the ergonomics
are unchanged:

use protovalidate_buffa::{ValidationError, Validate};

fn handle(req: &MyRequest) -> Result<(), ConnectError> {
    req.validate().map_err(|e| {
        // Match on the typed fields, not rule_id string prefixes.
        if e.compile_error.is_some() {
            // Schema-level mismatch caught at codegen — should not reach prod.
            ConnectError::new(Code::Internal, "validation schema error")
        } else if e.runtime_error.is_some() {
            // Rule precondition failed at runtime (e.g. non-UTF-8 under `pattern`).
            ConnectError::new(Code::Internal, "validation runtime error")
        } else {
            // The common path: field rule failures.
            e.into_connect_error()
        }
    })
}

Or just use #[connect_impl] and let the macro handle it for every handler
at once:

#[protovalidate_buffa::connect_impl]
impl MyService for MyServiceImpl {
    async fn create_user(
        &self,
        ctx: Context,
        request: OwnedView<pb::CreateUserRequestView<'static>>,
    ) -> Result<(pb::CreateUserResponse, Context), ConnectError> {
        // req.validate()? is inserted automatically — body only sees
        // already-validated requests.
    }
}

⬆️ Updated Dependencies

  • buffa → 0.7 across the workspace (buffa, buffa-build, buffa-codegen).
  • connectrpc → 0.7 (aligned with the buffa 0.7 transitive requirement,
    default features disabled).

Conformance

2872 / 2872 (100%) — every case in the upstream
protovalidate-conformance
suite passes, covering proto2, proto3, and editions 2023.


Installation

Library consumers — add to Cargo.toml:

[dependencies]
protovalidate-buffa = "0.5.0"

Codegen plugin — install from source:

cargo install \
  --git https://github.com/mathematic-inc/protovalidate-buffa \
  --tag protovalidate-buffa-protos-v0.5.0 \
  protoc-gen-protovalidate-buffa

Then wire it into buf.gen.yaml:

plugins:
  - local: protoc-gen-protovalidate-buffa
    out: gen/protovalidate
    strategy: all