Skip to content

Commit dfa7f64

Browse files
committed
Added lists support for enum cache json and fixed for skin check
1 parent 7018652 commit dfa7f64

File tree

2 files changed

+114
-13
lines changed

2 files changed

+114
-13
lines changed

src/Json/EnumCacheJson.cs

Lines changed: 113 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,132 @@
44
namespace PolyMod.Json;
55

66
/// <summary>
7-
/// Converts an <see cref="Enum"/> to and from a JSON string using the <see cref="EnumCache{T}"/>.
7+
/// A custom JSON converter for enum types that integrates with EnumCache.
8+
/// Supports serializing and deserializing enums by their cached string names,
9+
/// and works with both single enum values and property names.
810
/// </summary>
9-
/// <typeparam name="T">The type of the enum.</typeparam>
11+
/// <typeparam name="T">The enum type being converted.</typeparam>
1012
public class EnumCacheJson<T> : JsonConverter<T> where T : struct, Enum
1113
{
1214
/// <summary>
13-
/// Reads and converts the JSON to an enum value.
15+
/// Determines whether the converter can handle the given type.
16+
/// Supports both the enum type <typeparamref name="T"/> and <see cref="List{T}"/>.
1417
/// </summary>
15-
/// <param name="reader">The reader.</param>
16-
/// <param name="typeToConvert">The type to convert.</param>
17-
/// <param name="options">An object that specifies serialization options to use.</param>
18-
/// <returns>The converted value.</returns>
18+
/// <param name="typeToConvert">The type to check for compatibility.</param>
19+
/// <returns>True if the type can be converted; otherwise false.</returns>
20+
public override bool CanConvert(Type typeToConvert)
21+
{
22+
return typeToConvert == typeof(T) || typeToConvert == typeof(List<T>);
23+
}
24+
25+
/// <summary>
26+
/// Reads a JSON string and converts it into the corresponding enum value
27+
/// using the EnumCache lookup.
28+
/// </summary>
29+
/// <param name="reader">The JSON reader.</param>
30+
/// <param name="typeToConvert">The type to convert into.</param>
31+
/// <param name="options">Serialization options.</param>
32+
/// <returns>The enum value represented by the JSON string.</returns>
33+
/// <exception cref="NotSupportedException">Thrown if the type is not supported.</exception>
1934
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
2035
{
21-
return EnumCache<T>.GetType(reader.GetString());
36+
if (typeToConvert == typeof(T))
37+
{
38+
return EnumCache<T>.GetType(reader.GetString());
39+
}
40+
41+
throw new NotSupportedException("EnumCacheJson does not support reading this type directly.");
2242
}
2343

44+
2445
/// <summary>
25-
/// Writes a specified value as JSON.
46+
/// Writes the enum value as its cached string representation.
2647
/// </summary>
27-
/// <param name="writer">The writer to write to.</param>
28-
/// <param name="value">The value to convert to JSON.</param>
29-
/// <param name="options">An object that specifies serialization options to use.</param>
48+
/// <param name="writer">The JSON writer.</param>
49+
/// <param name="value">The enum value to write.</param>
50+
/// <param name="options">Serialization options.</param>
3051
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
3152
{
3253
writer.WriteStringValue(EnumCache<T>.GetName(value));
3354
}
55+
56+
/// <summary>
57+
/// Reads a JSON property name and converts it into the corresponding enum value.
58+
/// </summary>
59+
/// <param name="reader">The JSON reader.</param>
60+
/// <param name="typeToConvert">The target type.</param>
61+
/// <param name="options">Serialization options.</param>
62+
/// <returns>The enum value represented by the property name.</returns>
63+
public override T ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
64+
{
65+
return Read(ref reader, typeToConvert, options);
66+
}
67+
68+
/// <summary>
69+
/// Writes the enum value as a property name using its cached string representation.
70+
/// </summary>
71+
/// <param name="writer">The JSON writer.</param>
72+
/// <param name="value">The enum value to write.</param>
73+
/// <param name="options">Serialization options.</param>
74+
public override void WriteAsPropertyName(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
75+
{
76+
writer.WritePropertyName(EnumCache<T>.GetName(value));
77+
}
78+
}
79+
80+
/// <summary>
81+
/// A custom JSON converter for lists of enum values that integrates with EnumCache.
82+
/// Serializes enum values as strings and deserializes them back into a list of enums.
83+
/// </summary>
84+
/// <typeparam name="T">The enum type being converted.</typeparam>
85+
public class EnumCacheListJson<T> : JsonConverter<List<T>> where T : struct, Enum
86+
{
87+
/// <summary>
88+
/// Inner converter used to handle individual enum values.
89+
/// </summary>
90+
private readonly EnumCacheJson<T> _inner = new();
91+
92+
/// <summary>
93+
/// Reads a JSON array of enum string values and converts them into a list of enum values.
94+
/// </summary>
95+
/// <param name="reader">The JSON reader.</param>
96+
/// <param name="typeToConvert">The type to convert into.</param>
97+
/// <param name="options">Serialization options.</param>
98+
/// <returns>A list of enum values.</returns>
99+
/// <exception cref="JsonException">Thrown if the JSON is not an array.</exception>
100+
public override List<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
101+
{
102+
var list = new List<T>();
103+
104+
if (reader.TokenType != JsonTokenType.StartArray)
105+
throw new JsonException("Expected StartArray token for enum list");
106+
107+
while (reader.Read())
108+
{
109+
if (reader.TokenType == JsonTokenType.EndArray)
110+
break;
111+
112+
list.Add(_inner.Read(ref reader, typeof(T), options));
113+
}
114+
115+
return list;
116+
}
117+
118+
/// <summary>
119+
/// Writes a list of enum values as a JSON array of strings.
120+
/// </summary>
121+
/// <param name="writer">The JSON writer.</param>
122+
/// <param name="value">The list of enum values to write.</param>
123+
/// <param name="options">Serialization options.</param>
124+
public override void Write(Utf8JsonWriter writer, List<T> value, JsonSerializerOptions options)
125+
{
126+
writer.WriteStartArray();
127+
128+
foreach (var item in value)
129+
{
130+
_inner.Write(writer, item, options);
131+
}
132+
133+
writer.WriteEndArray();
134+
}
34135
}

src/Loader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ internal record TypeMapping(Type type, bool shouldCreateCache = true);
7373
foreach (var skin in skinValues)
7474
{
7575
string skinValue = skin.ToString();
76-
if (!Enum.TryParse<SkinType>(CultureInfo.CurrentCulture.TextInfo.ToTitleCase(skinValue), out _))
76+
if (!Enum.TryParse<SkinType>(skinValue, ignoreCase: true, out _))
7777
{
7878
EnumCache<SkinType>.AddMapping(skinValue.ToLowerInvariant(), (SkinType)Registry.autoidx);
7979
EnumCache<SkinType>.AddMapping(skinValue.ToLowerInvariant(), (SkinType)Registry.autoidx);

0 commit comments

Comments
 (0)