Randgalt / record-builder

Record builder generator for Java records
Apache License 2.0
756 stars 55 forks source link

Allow nullable arguments to be optional in StagedBuilders, allowing them to initialize during the final stage #170

Closed olsavmic closed 5 months ago

olsavmic commented 8 months ago

First of all, thank you for the Staged builders support! It helps us a lot to write null-safe code :)

For full adoption in our codebase though, we miss one specific convenience feature that doesn't add any runtime value, but helps tremendously in DX:

The original "reference" implementation supports the following:

All remaining optional, nullable, and collection attributes can be initialized on a final stage in any order.

I believe it would be a perfect feature in combination with the already existing interpretNotNulls option, combining both the safety and ease of use of the builder pattern.

Randgalt commented 8 months ago

The final stage has two methods, build() which builds an instance and builder() which returns a Record Builder builder. I would think that this builder accomplishes what you want right?

olsavmic commented 8 months ago

The final stage is theoretically usable. The issue is that currently, all fields are required to be filled by the staged builder, including the nullable ones (or those with default value / optional, depends on how far we want to take the idea).

What I would like is to have the possibility to generate staged builders only for required fields and then fill the optional ones only when needed.

@RecordBuilder
public record Foo(
    @Nullable String key,

    @Nullable String flag,

    @NotNull
    List<Item> items,

    @NotNull
    Long bar
              ) {}

->

FooBuilder.stagedBuilder()
    .items(List.of()) // required
    .bar(2) // required
    .builder() // preferrably, there should be no need to call the `builder` when all required stages are complete
    .flag("abc") // optional, key is skipped for example
    .build();
Randgalt commented 8 months ago

fill the optional ones only when needed.

It depends what you mean by optional. Record-Builder supports actually Optional<T> fields, nullable fields, etc. If we add builder() to each stage you'd get whatever Optional/null-able behavior that Record-Builder already has.

Randgalt commented 7 months ago

https://github.com/Randgalt/record-builder/pull/180