[Rust] Generate setters for optional primitive fields#1095
[Rust] Generate setters for optional primitive fields#1095leonardoarcari wants to merge 7 commits intoaeron-io:masterfrom
Conversation
|
@mward Can you please review this PR? Thanks. |
|
I'll take a look |
Appreciate it, @mward! |
…bGroup.java Co-authored-by: Leonardo Arcari <leonardo1.arcari@gmail.com>
|
looks good, thanks! |
Thanks for the quick turnaround @mward 💪 |
|
no problem |
|
IIUC, the SBE v1 specification permits optional non-scalar fields. For instance, there is an example where an enum is optional:
Source: SBE v1 Field Encoding As a user, I might expect
Is the aim that a user can, without "zeroing out" the underlying buffer, only set all the required fields and have a guarantee that any "lingering data" from a previous encode is overwritten? In other implementations, e.g., Java/C++, I've seen missing calls to |
c266263 to
50fab5b
Compare
@ZachBray Good catch, you are right! Pushed a change in 50fab5b to generate To clarify, I only nullify enum fields that are marked as @mward Can you take a look at these changes too? Thanks 🙏 |
@ZachBray Correct and imo it's even worse than that. Optional enum and fields can specify their own encoding for NullValue, so starting from a zero'd out buffer won't even do the trick. Code encoding SBE values would need to explicitly go through each optional field and set it to their NullValue not to cause havoc in Decoders. I know this is intentional, but in practice SBE users often get their types generated from schemas updated by many other people and it's easy to miss a new optional field added to the generated types. By |
My understanding is that the XML parser assigns fields presence values based on their types when left unspecified. According to the spec, if presence is specified at both levels, the values should align. Therefore, I think trusting the field level is fine in messages. When enums are inside composites, there are no surrounding field tokens carrying the presence information. Your code looks correct there: it pulls the presence value from the enum token. The change LGTM. Another question: in your implementation, does |

Problem
The Rust codegen has no actionable way to set optional scalar primitive fields to their
null-value, which is only made available as text in the generated docstring. Moreover, there's no uniform way tonull-initialize all optional primitive scalar fields at the Encoder level.In practice, callers have to remember and invoke each optional field setter individually with its null representation, which is error-prone, harder to audit, and easy to miss as schemas evolve.
Design Proposal
The generated encoders now expose a dedicated nullification path for optional primitive scalar fields:
Generated API Examples
This design improves ergonomics and correctness for callers that need deterministic “absent” encoding semantics, while keeping generated API behavior explicit across all encoder scopes.
Compatibility Decision
I considered changing the existing required-value setter signatures to accept
Option<T>directly.I did not take that path because it would be a breaking API change for existing generated-code consumers and would force updates across downstream codebases.
Instead, I introduced additive methods so existing call sites continue to compile unchanged, and clients can adopt optional-aware behavior incrementally.
Test Coverage Summary
The test suite covers:
Nonewhere expected.