Feature Request: Generate domain-specific Rust types for scalar fields
Maintainers usually reply within 2 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start by reviewing buffa-codegen and buffa_build::Config to understand how scalar fields and configuration are currently generated. Evaluate the proposed scalar_option, scalar_adapter, and fail_missing_adapter APIs, including ScalarAdapter conversions for binary and ProtoJSON paths. Done means domain-specific Rust scalar types are exposed while preserving the original wire and ProtoJSON representations.
Written by the indexing model from the issue text.
Description
Is there currently a practical way to generate domain-specific Rust types for protobuf scalar fields while preserving their original wire and ProtoJSON representations?
For example, given this protobuf definition:
message Dummy {
int32 id = 1;
double mass = 2;
}
I would like buffa-codegen to generate:
pub struct Dummy {
pub id: ::my_types::DummyId,
pub mass: ::uom::si::f64::Mass, // https://crates.io/crates/uom
}
As of Buffa 0.9.2, my understanding is that this is not supported.
extern_path can replace protobuf message or enum types, but it cannot replace an individual scalar field's Rust representation.
Implementing the entire containing message manually appears possible, but it is error-prone.
Replacing the scalar with a wrapper message would also change its wire and ProtoJSON representations.
Proposal:
One way this feature could work is through a custom protobuf option.
A custom option could be defined once and reused to attach semantic information to fields:
edition = "2024";
import "google/protobuf/descriptor.proto";
extend google.protobuf.FieldOptions {
string semantic_type = 51000 [retention = RETENTION_SOURCE];
}
message Dummy {
int32 id = 1 [(semantic_type) = "dummy.id"];
double mass = 2 [(semantic_type) = "mass.kilogram"];
}
Buffa could then provide an API mapping option values to Rust types and adapters:
buffa_build::Config::new()
.scalar_option(".semantic_type")
.scalar_adapter(
"dummy.id",
"::my_types::DummyId",
"::my_types::DummyIdAdapter",
)
.scalar_adapter(
"mass.kilogram",
"::uom::si::f64::Mass",
"::my_types::KilogramAdapter",
)
.fail_missing_adapter(); // fails if a field has a 'semantic_type' that is not mapped via 'scalar_adapter'
The user would select or define the domain types and implement the adapters:
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct DummyId(pub i32);
pub struct DummyIdAdapter;
impl buffa::ScalarAdapter<i32> for DummyIdAdapter {
type Value = DummyId;
fn from_wire(value: i32) -> DummyId {
DummyId(value)
}
fn to_wire(value: &DummyId) -> i32 {
value.0
}
}
pub struct KilogramAdapter;
impl buffa::ScalarAdapter<f64> for KilogramAdapter {
type Value = uom::si::f64::Mass;
fn from_wire(value: f64) -> Self::Value {
uom::si::f64::Mass::new::<uom::si::mass::kilogram>(value)
}
fn to_wire(value: &Self::Value) -> f64 {
value.get::<uom::si::mass::kilogram>()
}
}
Generated binary and ProtoJSON implementations would convert through the adapters, while owned and view APIs would expose the domain types.
Would this use case fit Buffa's direction?
- Dominant language
- Rust
- Stars
- 900
- Forks
- 95
- Avg merge
- 5d 10h
- Merged PRs (30d)
- 57
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from anthropics/buffa
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
anthropics/buffa#487 ·
Maintainers usually reply within 2 days
-
enhancement
Difficulty 4/5 3-5 days Newbie friendliness 55/100
anthropics/buffa#482 · 1 comment ·
Maintainers usually reply within 2 days
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
anthropics/buffa#463 ·
Maintainers usually reply within 2 days
-
Difficulty 3/5 1-2 days Newbie friendliness 72/100
anthropics/buffa#450 ·
Maintainers usually reply within 2 days
-
buffa-build: skip_debug to suppress the generated `impl Debug` for selected messages (prost parity)Open
Difficulty 4/5 3-5 days Newbie friendliness 68/100
anthropics/buffa#448 ·
Maintainers usually reply within 2 days
All issues in anthropics/buffa
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
area: cli bug priority: P2 ready-for-agent
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day