Skip to content

Commit

Permalink
Add code to enable deserializing tagged union using sealed class
Browse files Browse the repository at this point in the history
  • Loading branch information
zachauten committed Oct 25, 2024
1 parent 0fc3f87 commit 3dc8d98
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/main/java/app/work/Animal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package app.work;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract sealed class Animal {
@JsonProperty
String type;
}

final class Dog extends Animal {
@JsonProperty
String bone;
public Dog() {
this.type = "dog";
}
}
final class Cat extends Animal {
@JsonProperty
String milk;
public Cat() {
this.type = "cat";
}
}
8 changes: 8 additions & 0 deletions src/main/java/app/work/WorkController.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ public String hello() {
return "bar";
}

@PostMapping("parse")
public String parseADT(@RequestBody Animal animal) {
return switch(animal) {
case Dog d -> d.bone;
case Cat c -> c.milk;
};
}

@WithSpan
private void doSomeWork(int time) throws InterruptedException {
log.info("doing work for " + time + "ms");
Expand Down
42 changes: 42 additions & 0 deletions src/test/java/app/work/TestAnimal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package app.work;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.io.IOException;

import org.junit.Test;

import com.fasterxml.jackson.databind.ObjectMapper;

public class TestAnimal {
@Test
public void deserialize() throws IOException {
var file = new File("src/test/resources/dog.json");
Animal dog = new ObjectMapper().readerFor(Animal.class).readValue(file);

assertEquals("dog", dog.type);
assertEquals(Dog.class, dog.getClass());
}

@Test
public void testDeserializeDog() throws Exception {
String json = "{\"type\":\"dog\", \"bone\":\"chew toy\"}";

Animal animal = new ObjectMapper().readValue(json, Animal.class);
assertEquals(Dog.class, animal.getClass());
Dog dog = (Dog) animal;
assertEquals("chew toy", dog.bone);
}

@Test
public void testDeserializeCat() throws Exception {
String json = "{\"type\":\"cat\", \"milk\":\"almond milk\"}";

Animal animal = new ObjectMapper().readValue(json, Animal.class);
assertEquals(Cat.class, animal.getClass());
Cat cat = (Cat) animal;
assertEquals("almond milk", cat.milk);
}

}
4 changes: 4 additions & 0 deletions src/test/resources/dog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "dog",
"bone": "beef"
}

0 comments on commit 3dc8d98

Please sign in to comment.