Crell / Serde

Robust Serde (serialization/deserialization) library for PHP 8.
Other
299 stars 14 forks source link

Support renaming properties in flattened sub-objects #48

Closed Crell closed 10 months ago

Crell commented 12 months ago

Description

The tracking logic inside ObjectImporter was slightly buggy, and didn't support property renaming on objects that are being flattened/collected. Now it works.

While technically a bug fix, it enables much more convenient value objects so it's also an enhancement.

This also introduces a flattenPrefix directive, which lets flattened fields get a prefix defined by the parent class. That helps to avoid name collisions.

Motivation and context

Resolves #42.

How has this been tested?

Additional tests included.

Types of changes

What types of changes does your code introduce? Put an x in all the boxes that apply:

Crell commented 10 months ago

OK, I think I figured out an approach that will work. The PR now introduces a flattenPrefix directive, which is applied recursively. See the new tests for how it works. That should cover the needs in #42, for both single- and multi-value value objects.

Unless I hear a bug report in the next day or two, I will probably merge this and tag a 1.1 release on Tuesday or Wednesday.

@agustingomes @cnastasi Please confirm this solves your issue(s).

agustingomes commented 10 months ago

Thank you for working on this @Crell . I won't be able to verify it before Thursday, but if it solves the initial report from @cnastasi i'm sure it will work for my use case as well.

cnastasi commented 10 months ago

Hi @Crell, thanks for your work and effort, really appreciate it.

I just downloaded the branch and ran a few tests on my own.

Tell me if I'm wrong, but it covers only the cases when the name of the flattened field has the "serializedName" specified by the child as a part of the target field name.

Example: age -> min_age & max_age.

But what if:

Did I miss how to implement those cases, maybe?

What do you think?

Crell commented 10 months ago

The way the logic works is "whatever the Age class says this property should be called, add this string as a prefix."

So you could have a flattenPrefix of "min", and then on the property use serializedName: 'Age', or renameWith: Cases:Capitalized (if the property is named age). That should give you a minAge field in the output.

You can fully rename the field if you want. As shown in the examples, the actual property name is value. But in the output, it is "min_age", because of the combination of flattenPrefix and serializedName.

I don't know what you mean by "same name of the parent field." The name of the property in the parent is currently irrelevant, I believe. The prefix can match it or not, as you prefer.

Crell commented 10 months ago

This seems like it resolves the issue, so I'm going to tag a new release shortly. Thanks all! As a fan of value objects I'm glad to see I'm not alone. :smile: