micronaut-projects / micronaut-serialization

Build Time Serialization APIs for Micronaut
Apache License 2.0
26 stars 18 forks source link

Property Level Serializer or Deserializer not working #843

Open nicolasmingo opened 4 months ago

nicolasmingo commented 4 months ago

Hi, I've followed the micronaut guide to use custom serializer/deserializer, but using this feature in property level seems not working.

import com.fasterxml.jackson.annotation.JsonProperty;
import io.micronaut.context.annotation.Secondary;
import io.micronaut.core.type.Argument;
import io.micronaut.serde.Decoder;
import io.micronaut.serde.Encoder;
import io.micronaut.serde.ObjectMapper;
import io.micronaut.serde.Serde;
import io.micronaut.serde.annotation.Serdeable;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.Objects;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@MicronautTest
class BugPropTest {

    @Inject
    ObjectMapper objectMapper;

    @Test void serNotWorking() throws IOException {
        Place place = new Place(
                Point.valueOf(1, 1)
        );

        //
        String json = objectMapper.writeValueAsString(
                place
        );
        assertEquals("{ \"point\": [1, 1] }", json); // FIXME json returns "{}"
    }

    @Test void deserNotWorking() throws IOException {
        String json = "{ \"point\": [1, 1] }";
        Place deserPlace = objectMapper.readValue(json, Place.class);
        assertNotNull(deserPlace);
        assertNotNull(deserPlace.point); // FIXME deserPlace.point = null
        int[] coords = deserPlace.point.coords();
        assertEquals(1, coords[0]);
        assertEquals(1, coords[1]);
    }

    //

    @Singleton
    @Secondary // (1)
    public static class ReversePointSerde implements Serde<Point> {
        @Override
        public Point deserialize(
                Decoder decoder,
                DecoderContext context,
                Argument<? super Point> type) throws IOException {
            Decoder array = decoder.decodeArray();
            int y = array.decodeInt(); // (2)
            int x = array.decodeInt();
            array.finishStructure();
            return Point.valueOf(x, y);
        }

        @Override
        public void serialize(
                Encoder encoder,
                EncoderContext context,
                Argument<? extends Point> type, Point value) throws IOException {
            Objects.requireNonNull(value, "Point cannot be null");
            int[] coords = value.coords();
            Encoder array = encoder.encodeArray(type);
            array.encodeInt(coords[1]); // (3)
            array.encodeInt(coords[0]);
            array.finishStructure();
        }
    }

    @Serdeable
    public static class Place {
        @Serdeable.Serializable(using = ReversePointSerde.class) // (1)
        @Serdeable.Deserializable(using = ReversePointSerde.class) // (2)
        @JsonProperty("point")
        public Point point;

        public Place() {

        }

        public Place(Point point) {
            this.point = point;
        }

    }
}

Expected Behavior

2 Test success

Actual Behaviour

Both tests (ser/deser) are failing

Steps To Reproduce

  1. Copy the code inside a test class
  2. Run unit test
  3. See results

Environment Information

Example Application

No response

Version

4.4.2

dstepanov commented 4 months ago

Please create a sample project