Skip to content

Commit 2c82d77

Browse files
committed
add enum ordinal codec
1 parent 1e69070 commit 2c82d77

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

json/src/main/java/alpine/json/codec/Codec.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,26 @@ public <R> R encode(Transcoder<R> transcoder, E value) {
142142
};
143143
}
144144

145+
static <E extends Enum<E>> Codec<E> ordinal(Class<E> enumClass) {
146+
return new Codec<>() {
147+
@Override
148+
public <R> E decode(Transcoder<R> transcoder, R value) {
149+
var ordinal = (int) transcoder.decodeNumber(value);
150+
151+
if (ordinal >= enumClass.getEnumConstants().length) {
152+
throw new DecodingException("Enum ordinal out of bounds: " + ordinal);
153+
}
154+
155+
return enumClass.getEnumConstants()[ordinal];
156+
}
157+
158+
@Override
159+
public <R> R encode(Transcoder<R> transcoder, E value) {
160+
return transcoder.encodeNumber(value.ordinal());
161+
}
162+
};
163+
}
164+
145165
default FlatCodec<T> flatten() {
146166
return new FlatCodec<>(this);
147167
}

json/src/test/java/alpine/json/JsonCodecTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void testPrimitiveArray() {
152152
}
153153

154154
@Test
155-
void testEnum() {
155+
void testEnumName() {
156156
var codec = Codec.name(Direction.class);
157157
assertEquals(string("north"), codec.encode(Transcoder.JSON, Direction.NORTH));
158158
assertEquals(Direction.SOUTH, codec.decode(Transcoder.JSON, string("south")));
@@ -164,6 +164,19 @@ void testEnum() {
164164
assertThrows(Exception.class, () -> codec.decode(Transcoder.JSON, string("up")));
165165
}
166166

167+
@Test
168+
void testEnumOrdinal() {
169+
var codec = Codec.ordinal(Direction.class);
170+
assertEquals(number(0), codec.encode(Transcoder.JSON, Direction.NORTH));
171+
assertEquals(Direction.SOUTH, codec.decode(Transcoder.JSON, number(1)));
172+
173+
for (var direction : Direction.values()) {
174+
assertEquals(direction, codec.decode(Transcoder.JSON, codec.encode(Transcoder.JSON, direction)));
175+
}
176+
177+
assertThrows(Exception.class, () -> codec.decode(Transcoder.JSON, number(999)));
178+
}
179+
167180
@Test
168181
void testUuid() {
169182
var uuid = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");

0 commit comments

Comments
 (0)