roookeee / datus

datus enables you to define a conversion process between two data structures in a fluent functional API
MIT License
41 stars 5 forks source link

Add a nullsafe mode #21

Closed roookeee closed 5 years ago

roookeee commented 5 years ago

As much as datus is about explicitness: traversing nested objects which can be null is quite cumbersome as it stands.

We have to find a way to avoid something like this:

.from(Order::getCustomer)
    .given(Objects::nonNull, Customer::getBillingAddress).orElseNull()
    .given(Objects::nonNull, Address::getCity).orElseNull()
    .into(OrderDTO::setBillingCity)

I personally would like to veto any variant that would make every mapping step of a mapping definition nullsafe - it's too implicit.

roookeee commented 5 years ago

Maybe add a nullsafe() function that turns all map calls etc. into implicit null safe variants. This looks like the most elegant solution, but we lose explicitness and pay a slight performance penalty for any subsequent intra-step maps that don't need to handle null.

EDIT: Thinking about it: when nullsafe() is used all subsequent steps have to be null safe too so this argument is void

roookeee commented 5 years ago

Add a mapNullsafe() (bad name, just an example) ? It's quite verbose but has no other drawbacks compared to the aforementioned variant.

On the other hand: once you have done one mapNullSafe() all the following steps have to be nullsafe too which makes this approach less appealing

roookeee commented 5 years ago

A working implementaion is in PR #22. Instead of adding a boolean flag for the implicit null checking I opted for an extendable enum to not break the public APIs as easily in the future

roookeee commented 5 years ago

Will probably do a 1.3.0 release this weekend that includes this feature as it's quite useful

roookeee commented 5 years ago

This feature will be released tomorrow after a local review

roookeee commented 5 years ago

Released