raynigon / unit-api

Raynigon Unit Api - JSR-385
https://unit-api.raynigon.com/
Apache License 2.0
8 stars 2 forks source link

Enhancement: Improve Serialization of Quantity to Use Unit Symbol Instead of Class #544

Open k1ng-maus opened 4 months ago

k1ng-maus commented 4 months ago

Description: Currently, the serialization of Quantity objects in the library always displays the unit based on its class, as defined by the custom SystemOfUnits. This can be limiting and less readable, especially when the symbol of the unit is more meaningful.

Here is an example of the current behavior with the relevant code snippets:

public interface IPackagedItem<T extends IPackagedItem<T>> extends Quantity<T> {
}

public interface IBox extends IPackagedItem<IBox> {
}

public interface IBottle extends IPackagedItem<IBottle> {
}

public class Box1 extends BaseUnit<IBox> {
    public Box1() {
        super(CustomSystemOfUnits.CUSTOM_UNITS_NAME, CustomSystemOfUnits.BOX_1_SYMBOL, "Box 1", IBox.class, UnitDimension.NONE);
    }
}

public class Box5 extends ScaledUnit<IBox> {
    public Box5() {
        super(5, BOX_1, CustomSystemOfUnits.BOX_5_SYMBOL, "Box 5");
    }
}

public class Bottle330ml extends BaseUnit<IBottle> {
    public Bottle330ml() {
        super(CustomSystemOfUnits.CUSTOM_UNITS_NAME, CustomSystemOfUnits.BOTTLE_330ML_SYMBOL, "Bottle 330ml", IBottle.class, UnitDimension.NONE);
    }
}

public class Bottle500ml extends ScaledUnit<IBottle> {
    public Bottle500ml() {
        super(500.0 / 330.0, BOTTLE_330ML, CustomSystemOfUnits.BOTTLE_500ML_SYMBOL, "Bottle 500ml");
    }
}

Here is a sample DTO and controller:

import lombok.Getter;
import lombok.Setter;
import rs.codeeco.custom.IPackagedItem;

import javax.measure.Quantity;

@Getter
@Setter
public class CustomQuantityPayloadDto2 {
    private Quantity<? extends IPackagedItem<?>> q1;
}

@GetMapping("/read/custom/v2")
public CustomQuantityPayloadDto2 readCustomV2() {
    CustomQuantityPayloadDto2 dto = new CustomQuantityPayloadDto2();

    Quantity<IBox> option1 = UnitsApiService.quantity(6, CustomSystemOfUnits.BOX_20);
    Quantity<IBottle> option2 = UnitsApiService.quantity(3, CustomSystemOfUnits.BOTTLE_500ML);

    final Quantity<? extends IPackagedItem<?>> option = random.nextBoolean()
            ? option1
            : option2;
    dto.setQ1(option);

    return dto;
}

In this example, the serialization always displays the unit based on the class, which can be less intuitive.

Improvement Proposal: I propose enhancing the serializer to print the unit using its symbol instead of its class, if possible. This would make the serialized output more readable and meaningful.

Example of the Desired Behavior: When serialized, the Quantity object should use the unit symbol:

{
    "q1": "6 Box20"
}

This change would enhance usability, especially when dealing with various custom units.

Implementation Offer: I am willing to implement this feature if it is acceptable. Please let me know if this proposal is approved, and I will start working on the implementation.

Thank you for considering this enhancement.

raynigon commented 3 months ago

I am not sure if I understand your intention correctly. IMO the Bottle should have a property with a Quantity type and not derive from a Quantity class. There should only be one implementation of the Quantity Type, which is the NumberedQuantity.

Could you elaborate your use case a little bit more, please?