Skip to content

Commit a410aee

Browse files
committed
Added some useful codecs
1 parent c808e0b commit a410aee

File tree

3 files changed

+203
-1
lines changed

3 files changed

+203
-1
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ AgeUtil
3737
3838
DatChatFormatting
3939
> A set of standardised chat colours for consistently formatting chat messages
40-
>
40+
41+
DatCodec
42+
> A few useful codecs for serialising common values
43+
>
44+
> Currently Implemented: UUID, Enums, ChunkPos
4145
4246
DatMessageFormatter
4347
> A utility for formatting strings into chat Components using variable replacements and shorthands for formatting directives
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.datdeveloper.datmoddingapi.util;
2+
3+
import com.mojang.serialization.Codec;
4+
import com.mojang.serialization.DataResult;
5+
import net.minecraft.Util;
6+
import net.minecraft.world.level.ChunkPos;
7+
8+
import java.util.UUID;
9+
import java.util.stream.IntStream;
10+
11+
/**
12+
* A utility class containing various useful codecs
13+
*/
14+
public class DatCodec {
15+
/**
16+
* A Codec for handling UUID
17+
* <br>
18+
* Converts it into a string for storage
19+
*/
20+
public static final Codec<UUID> UUID_CODEC = Codec.STRING.comapFlatMap(s -> {
21+
try {
22+
return DataResult.success(UUID.fromString(s));
23+
} catch (final IllegalArgumentException e) {
24+
return DataResult.error(() -> s + " is not a UUID.");
25+
}
26+
}, UUID::toString);
27+
28+
/**
29+
* A helper function to create a Codec that handles the given enum class
30+
* <br>
31+
* The resulting codec will convert the enum into a string for storage
32+
* @param enumClass The class of the enum
33+
* @return A Codec that handles the given enum class
34+
* @param <E> The Enum Type
35+
*/
36+
public static <E extends Enum<E>> Codec<E> getEnumCodec(final Class<E> enumClass) {
37+
return Codec.STRING.comapFlatMap(string -> {
38+
try {
39+
return DataResult.success(E.valueOf(enumClass, string));
40+
} catch (final IllegalArgumentException e) {
41+
return DataResult.error(() -> string + " is not an instance of the enum");
42+
}
43+
}, E::name);
44+
}
45+
46+
/**
47+
* A Codec for handling ChunkPos
48+
* <br>
49+
* This converts the chunkpos into an intstream, similar to {@link net.minecraft.core.BlockPos}
50+
* @see net.minecraft.core.BlockPos
51+
*/
52+
public static final Codec<ChunkPos> CHUNKPOS = Codec.INT_STREAM.comapFlatMap(stream ->
53+
Util.fixedSize(stream, 2).map((ints -> new ChunkPos(ints[0], ints[1]))),
54+
chunkPos -> IntStream.of(chunkPos.x, chunkPos.z)
55+
);
56+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package com.datdeveloper;
2+
3+
import com.datdeveloper.datmoddingapi.util.DatCodec;
4+
import com.datdeveloper.datmoddingapi.util.ENotificationType;
5+
import com.google.gson.Gson;
6+
import com.google.gson.JsonArray;
7+
import com.google.gson.JsonElement;
8+
import com.mojang.serialization.JsonOps;
9+
import net.minecraft.world.level.ChunkPos;
10+
import org.junit.jupiter.api.Assertions;
11+
import org.junit.jupiter.api.Test;
12+
13+
import java.util.Optional;
14+
import java.util.UUID;
15+
16+
public class TestCodecs {
17+
/**
18+
* Test UUID Correctly converts to Json
19+
*/
20+
@Test
21+
void testUuidToJson() {
22+
final UUID uuid = UUID.randomUUID();
23+
24+
final Optional<JsonElement> result = DatCodec.UUID_CODEC.encodeStart(JsonOps.INSTANCE, uuid).result();
25+
26+
Assertions.assertTrue(result.isPresent());
27+
Assertions.assertEquals(uuid.toString(), result.get().getAsString());
28+
}
29+
30+
/**
31+
* Test Json correctly converts into UUID
32+
*/
33+
@Test
34+
void testJsonToUuid() {
35+
final UUID uuid = UUID.randomUUID();
36+
37+
final Gson gson = new Gson();
38+
final JsonElement object = gson.toJsonTree(uuid.toString());
39+
40+
final Optional<UUID> result = DatCodec.UUID_CODEC.parse(JsonOps.INSTANCE, object).result();
41+
42+
Assertions.assertTrue(result.isPresent());
43+
Assertions.assertEquals(uuid, result.get());
44+
}
45+
46+
/**
47+
* Test Json to UUID correctly handles bad UUID
48+
*/
49+
@Test
50+
void testBadJsonToUuid() {
51+
final Gson gson = new Gson();
52+
final JsonElement object = gson.toJsonTree("Totally not a real UUID");
53+
54+
final Optional<UUID> result = DatCodec.UUID_CODEC.parse(JsonOps.INSTANCE, object).result();
55+
56+
Assertions.assertFalse(result.isPresent());
57+
}
58+
59+
/**
60+
* Test enum correctly converts to json
61+
*/
62+
@Test
63+
void testEnumToJson() {
64+
final ENotificationType test = ENotificationType.ACTIONBAR;
65+
66+
final Optional<JsonElement> result = DatCodec.getEnumCodec(ENotificationType.class).encodeStart(JsonOps.INSTANCE, test).result();
67+
68+
Assertions.assertTrue(result.isPresent());
69+
Assertions.assertEquals(test.name(), result.get().getAsString());
70+
}
71+
72+
/**
73+
* Test Json correctly converts into Enum
74+
*/
75+
@Test
76+
void testJsonToEnum() {
77+
final ENotificationType test = ENotificationType.ACTIONBAR;
78+
79+
final Gson gson = new Gson();
80+
final JsonElement object = gson.toJsonTree(test.name());
81+
82+
final Optional<ENotificationType> result = DatCodec.getEnumCodec(ENotificationType.class).parse(JsonOps.INSTANCE, object).result();
83+
84+
Assertions.assertTrue(result.isPresent());
85+
Assertions.assertEquals(test, result.get());
86+
}
87+
88+
/**
89+
* Test Json to enum correctly handles bad enum
90+
*/
91+
@Test
92+
void testBadJsonToEnum() {
93+
final Gson gson = new Gson();
94+
final JsonElement object = gson.toJsonTree("Totally not a real ENotificationType");
95+
96+
final Optional<ENotificationType> result = DatCodec.getEnumCodec(ENotificationType.class).parse(JsonOps.INSTANCE, object).result();
97+
98+
Assertions.assertFalse(result.isPresent());
99+
}
100+
101+
/**
102+
* Test ChunkPos correctly converts to json
103+
*/
104+
@Test
105+
void testChunkPosToJson() {
106+
final ChunkPos chunkPos = new ChunkPos(5, 12);
107+
108+
final Optional<JsonElement> result = DatCodec.CHUNKPOS.encodeStart(JsonOps.INSTANCE, chunkPos).result();
109+
110+
Assertions.assertTrue(result.isPresent());
111+
Assertions.assertEquals("[" + chunkPos.x + "," + chunkPos.z + "]", result.get().toString());
112+
}
113+
114+
/**
115+
* Test Json correctly converts into ChunkPos
116+
*/
117+
@Test
118+
void testJsonToChunkPos() {
119+
120+
final ChunkPos chunkPos = new ChunkPos(5, 12);
121+
final Gson gson = new Gson();
122+
final JsonElement object = gson.fromJson("[" + chunkPos.x + "," + chunkPos.z + "]", JsonArray.class);
123+
124+
final Optional<ChunkPos> result = DatCodec.CHUNKPOS.parse(JsonOps.INSTANCE, object).result();
125+
126+
Assertions.assertTrue(result.isPresent());
127+
Assertions.assertEquals(chunkPos, result.get());
128+
}
129+
130+
/**
131+
* Test Json to enum correctly handles bad enum
132+
*/
133+
@Test
134+
void testBadJsonToBlockPos() {
135+
final Gson gson = new Gson();
136+
final JsonElement object = gson.fromJson("[1,2,3,4,5,6]", JsonArray.class);
137+
138+
final Optional<ChunkPos> result = DatCodec.CHUNKPOS.parse(JsonOps.INSTANCE, object).result();
139+
140+
Assertions.assertFalse(result.isPresent());
141+
}
142+
}

0 commit comments

Comments
 (0)