Skip to content

Commit

Permalink
[json-core] Add SimpleMapper.Type list() and map() methods
Browse files Browse the repository at this point in the history
  • Loading branch information
rbygrave committed Dec 16, 2024
1 parent 0541c6f commit c5755b7
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 10 deletions.
15 changes: 15 additions & 0 deletions json-core/src/main/java/io/avaje/json/simple/DTypeMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import io.avaje.json.JsonException;
import io.avaje.json.JsonReader;
import io.avaje.json.JsonWriter;
import io.avaje.json.core.CoreTypes;
import io.avaje.json.stream.BufferedJsonWriter;
import io.avaje.json.stream.BytesJsonWriter;
import io.avaje.json.stream.JsonStream;

import java.io.*;
import java.util.List;
import java.util.Map;

final class DTypeMapper<T> implements SimpleMapper.Type<T> {

Expand All @@ -20,6 +23,18 @@ final class DTypeMapper<T> implements SimpleMapper.Type<T> {
this.jsonStream = jsonStream;
}

@Override
public SimpleMapper.Type<List<T>> list() {
final JsonAdapter<List<T>> list = CoreTypes.createList(adapter);
return new DTypeMapper<>(list, jsonStream);
}

@Override
public SimpleMapper.Type<Map<String, T>> map() {
final JsonAdapter<Map<String, T>> map = CoreTypes.createMap(adapter);
return new DTypeMapper<>(map, jsonStream);
}

@Override
public T fromJson(JsonReader reader) {
return adapter.fromJson(reader);
Expand Down
10 changes: 10 additions & 0 deletions json-core/src/main/java/io/avaje/json/simple/SimpleMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ interface Builder {
*/
interface Type<T> {

/**
* Create a list type for this type.
*/
Type<List<T>> list();

/**
* Create a map type with string keys and this type as the value type.
*/
Type<Map<String, T>> map();

/**
* Read the return the value from the json content.
*/
Expand Down
2 changes: 1 addition & 1 deletion json-core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
exports io.avaje.json.simple;
exports io.avaje.json.stream;
exports io.avaje.json.view;
exports io.avaje.json.core to io.avaje.jsonb;
exports io.avaje.json.core to io.avaje.jsonb, io.avaje.json.node;

requires static io.helidon.webserver;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
import io.avaje.json.JsonWriter;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;

class CustomAdapterTest {

static final SimpleMapper simpleMapper = SimpleMapper.builder().build();
static final MyAdapter myAdapter = new MyAdapter(simpleMapper);
static final SimpleMapper.Type<MyCustomType> type = simpleMapper.type(myAdapter);

@Test
void mapUsingCustomAdapter() {

MyAdapter myAdapter = new MyAdapter(simpleMapper);

SimpleMapper.Type<MyCustomType> type = simpleMapper.type(myAdapter);

MyCustomType source = new MyCustomType();
source.foo = "hi";
source.bar = 42;
Expand All @@ -31,9 +31,57 @@ void mapUsingCustomAdapter() {
assertThat(fromJson.bar).isEqualTo(source.bar);
}

@Test
void list() {
SimpleMapper.Type<List<MyCustomType>> listType = type.list();

var v0 = as("a", 1);
var v1 = as("b", 2);
var list = List.of(v0, v1);

String asJson = listType.toJson(list);

List<MyCustomType> fromJson = listType.fromJson(asJson);
assertThat(fromJson).isEqualTo(list);
}

@Test
void map() {
SimpleMapper.Type<Map<String, MyCustomType>> mapType = type.map();

var v0 = as("a", 1);
var v1 = as("b", 2);
Map<String, MyCustomType> map = Map.of("one", v0, "two", v1);

String asJson = mapType.toJson(map);

var fromJson = mapType.fromJson(asJson);
assertThat(fromJson).isEqualTo(map);
}

private MyCustomType as(String foo, int bar) {
MyCustomType customType = new MyCustomType();
customType.foo = foo;
customType.bar = bar;
return customType;
}

static class MyCustomType {
public String foo;
public int bar;

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof MyCustomType)) return false;
MyCustomType that = (MyCustomType) object;
return bar == that.bar && Objects.equals(foo, that.foo);
}

@Override
public int hashCode() {
return Objects.hash(foo, bar);
}
}

static class MyAdapter implements JsonAdapter<MyCustomType> {
Expand Down
15 changes: 15 additions & 0 deletions json-node/src/main/java/io/avaje/json/node/adapter/DMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
import io.avaje.json.JsonException;
import io.avaje.json.JsonReader;
import io.avaje.json.JsonWriter;
import io.avaje.json.core.CoreTypes;
import io.avaje.json.simple.SimpleMapper;
import io.avaje.json.stream.BufferedJsonWriter;
import io.avaje.json.stream.BytesJsonWriter;
import io.avaje.json.stream.JsonStream;

import java.io.*;
import java.util.List;
import java.util.Map;

final class DMapper<T> implements SimpleMapper.Type<T> {

Expand All @@ -21,6 +24,18 @@ final class DMapper<T> implements SimpleMapper.Type<T> {
this.jsonStream = jsonStream;
}

@Override
public SimpleMapper.Type<List<T>> list() {
final JsonAdapter<List<T>> list = CoreTypes.createList(adapter);
return new DMapper<>(list, jsonStream);
}

@Override
public SimpleMapper.Type<Map<String, T>> map() {
final JsonAdapter<Map<String, T>> map = CoreTypes.createMap(adapter);
return new DMapper<>(map, jsonStream);
}

@Override
public T fromJson(JsonReader reader) {
return adapter.fromJson(reader);
Expand Down
59 changes: 54 additions & 5 deletions json-node/src/test/java/io/avaje/json/node/CustomAdapterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@
import io.avaje.json.simple.SimpleMapper;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;

class CustomAdapterTest {

static final JsonNodeMapper mapper = JsonNodeMapper.builder().build();
static final MyAdapter myAdapter = new MyAdapter(mapper);
static final SimpleMapper.Type<MyCustomType> typeMapper = mapper.mapper(myAdapter);

@Test
void mapUsingCustomAdapter() {

MyAdapter myAdapter = new MyAdapter(mapper);

SimpleMapper.Type<MyCustomType> typeMapper = mapper.mapper(myAdapter);

MyCustomType source = new MyCustomType();
source.foo = "hi";
source.bar = 42;
Expand All @@ -30,9 +31,57 @@ void mapUsingCustomAdapter() {
assertThat(fromJson.bar).isEqualTo(source.bar);
}

@Test
void list() {
SimpleMapper.Type<List<MyCustomType>> listType = typeMapper.list();

var v0 = as("a", 1);
var v1 = as("b", 2);
var list = List.of(v0, v1);

String asJson = listType.toJson(list);

List<MyCustomType> fromJson = listType.fromJson(asJson);
assertThat(fromJson).isEqualTo(list);
}

@Test
void map() {
SimpleMapper.Type<Map<String, MyCustomType>> mapType = typeMapper.map();

var v0 = as("a", 1);
var v1 = as("b", 2);
Map<String, MyCustomType> map = Map.of("one", v0, "two", v1);

String asJson = mapType.toJson(map);

var fromJson = mapType.fromJson(asJson);
assertThat(fromJson).isEqualTo(map);
}

private MyCustomType as(String foo, int bar) {
MyCustomType customType = new MyCustomType();
customType.foo = foo;
customType.bar = bar;
return customType;
}

static class MyCustomType {
public String foo;
public int bar;

@Override
public boolean equals(Object object) {
if (this == object) return true;
if (!(object instanceof MyCustomType)) return false;
MyCustomType that = (MyCustomType) object;
return bar == that.bar && Objects.equals(foo, that.foo);
}

@Override
public int hashCode() {
return Objects.hash(foo, bar);
}
}

static class MyAdapter implements JsonAdapter<MyCustomType> {
Expand Down

0 comments on commit c5755b7

Please sign in to comment.