- 
                Notifications
    You must be signed in to change notification settings 
- Fork 57
Closed
Description
What
Currently, SortedMap and ImmutableSortedMap can be serialized, but can't be deserialized.
It would be desirable to have that feature, even though it's somewhat of a niche use-case.
How to reproduce
	@Test
	void foo() throws Exception {
		final var mapper = new ObjectMapper();
		mapper.registerModule(new EclipseCollectionsModule());
		final var foo = new Foo(SortedMaps.immutable.empty());
		final var json = mapper.writeValueAsString(foo);
		assertThatThrownBy(() -> mapper.readValue(json, Foo.class))
		        .isInstanceOf(JsonMappingException.class);
	}
	@Test
	void bar() throws Exception {
		final var mapper = new ObjectMapper();
		mapper.registerModule(new EclipseCollectionsModule());
		final var bar = new Bar(SortedMaps.mutable.empty());
		final var json = mapper.writeValueAsString(bar);
		assertThatThrownBy(() -> mapper.readValue(json, Bar.class))
		        .isInstanceOf(JsonMappingException.class);
	}
	private record Foo(ImmutableSortedMap<String, Object> values) {
	}
	private record Bar(MutableSortedMap<String, Object> values) {
	}Analysis
Deserializers are initalized in a static block in com.fasterxml.jackson.datatype.eclipsecollections.deser.map.EclipseMapDeserializers.
While Object to Object maps can be SortedMapIterable, there are no such equivalent for primitives.
As such, the fix could be as simple as adding a new constant in com.fasterxml.jackson.datatype.eclipsecollections.deser.map.TypeHandlerPair :
    TypeHandlerPair<MutableSortedMap<Object, Object>, RefKeyHandler, RefValueHandler> COMPARABLE_OBJECT =
            new TypeHandlerPair<MutableSortedMap<Object, Object>, RefKeyHandler, RefValueHandler>() {
                @Override
                public RefKeyHandler keyHandler(JavaType type) {
                    return new RefKeyHandler(type, null);
                }
                @Override
                public RefValueHandler valueHandler(JavaType type) {
                    return new RefValueHandler(type, null, null);
                }
                @Override
                public MutableMap<Object, Object> createEmpty() {
                    return SortedMaps.mutable.empty();
                }
                @Override
                public void add(
                        MutableSortedMap<Object, Object> target,
                        RefKeyHandler kh, RefValueHandler vh,
                        DeserializationContext ctx, String k, JsonParser v
                ) throws IOException {
                    target.put(kh.key(ctx, k), vh.value(ctx, v));
                }
            };And then, in EclipseMapDeserializers :
    static {
        add(MutableMap.class, TypeHandlerPair.OBJECT_OBJECT);
        add(MutableMapIterable.class, TypeHandlerPair.OBJECT_OBJECT);
        add(MapIterable.class, TypeHandlerPair.OBJECT_OBJECT);
        add(UnsortedMapIterable.class, TypeHandlerPair.OBJECT_OBJECT);
        add(ImmutableMap.class, TypeHandlerPair.OBJECT_OBJECT, MutableMap::toImmutable);
        add(ImmutableMapIterable.class, TypeHandlerPair.OBJECT_OBJECT, MutableMap::toImmutable);
+        add(MutableSortedMap.class, TypeHandlerPair.COMPARABLE_OBJECT);
+        add(SortedMapIterable.class, TypeHandlerPair.COMPARABLE_OBJECT);
+        add(ImmutableSortedMap.class, TypeHandlerPair.COMPARABLE_OBJECT, MutableSortedMap::toImmutable);Note that this solution only handles java.lang.Comparable keys, as we can't rely on SortedMaps.mutable.empty(Comparator<? super K> comparator).