Skip to content

buffa-test-fixtures: minimal #[derive(Message)] for tests and doc examples #226

Description

@iainmcgin

Motivation

While spiking a buffa port for axum-extra's protobuf extractor, the main ergonomics gap relative to prost was the lack of an inline #[derive] for test and example code. prost users write:

#[derive(prost::Message)]
struct Input {
    #[prost(string, tag = "1")]
    foo: String,
}

directly inside #[cfg(test)] modules and doc examples. buffa is codegen-only, so the equivalent today is either:

  • pull in buffa-types and use a well-known type (StringValue, Int32Value) as a stand-in fixture, or
  • add a build.rs + .proto file just for tests.

The first works but reads oddly in docs ("where MyMessage is a type generated by protoc-gen-buffa…"); the second is heavyweight for a downstream crate that only wants one tiny test message.

This will recur on every downstream port (prometheus-client, pprof, libp2p-identity, etc.) — each has prost-derive test fixtures that need a buffa equivalent.

Proposal

A buffa-test-fixtures crate (or buffa-derive, name TBD) that provides a #[derive(buffa::Message)] proc-macro covering the minimal field set needed for tests and examples:

  • scalar fields (string, int32, int64, uint32, uint64, bool, bytes)
  • optional / repeated
  • nested messages
  • explicit tag = N

Explicitly out of scope (to keep it from becoming a parallel production codegen path): maps, oneofs, enums, groups, extensions, editions feature resolution, view types, reflection, JSON/textproto. If a test needs those, it should use real codegen.

Positioning

The crate docs and README should be unambiguous that this is for tests and examples only — protoc-gen-buffa / buffa-build remain the supported path for production schemas. Something along the lines of:

This derive exists so downstream crates can write self-contained tests and doc examples without a build.rs. It supports a deliberately small subset of protobuf. For application code, generate types from .proto files.

A #[doc(hidden)] re-export from the main buffa crate behind a derive feature would let examples write #[derive(buffa::Message)] without a second dependency line, but that may invite production use — open to leaving it as a separate explicit dep instead.

Prior art

  • prost's prost-derive (the thing we're matching ergonomically)
  • serde's split between serde and serde_derive

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions