Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error message for validation errors in System.Test.Json deserialization #735

Merged
merged 8 commits into from
Jan 8, 2025
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,49 @@ namespace Vogen.Generators.Conversions;

internal class GenerateSystemTextJsonConversions : IGenerateConversion
{
private static string GenerateDeserializeJsonMethod(VoWorkItem item) => $$"""
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
#endif
private static void ThrowJsonExceptionWhenValidationFails(Vogen.Validation validation)
{
var e = ThrowHelper.CreateValidationException(validation);
throw new global::System.Text.Json.JsonException(null, e);
}
{{GenerateThrowExceptionHelperIfNeeded(item)}}

public static VOTYPE DeserializeJson(VOUNDERLYINGTYPE value)
{
{{GenerateNullCheckAndThrowJsonExceptionIfNeeded(item)}}
{{Util.GenerateCallToNormalizeMethodIfNeeded(item)}}

{{Util.GenerateCallToValidationAndThrowIfRequired(item, "ThrowJsonExceptionWhenValidationFails")}}

return new VOTYPE(value);
}
"""
.Replace("\n", "\n ");

private static string GenerateThrowExceptionHelperIfNeeded(VoWorkItem voWorkItem) =>
voWorkItem.IsTheUnderlyingAValueType ? string.Empty
: """

private static void ThrowJsonExceptionWhenNull(VOUNDERLYINGTYPE value)
{
if (value == null)
{
var e = ThrowHelper.CreateCannotBeNullException();
throw new global::System.Text.Json.JsonException(null, e);
}
}
""";

private static string GenerateNullCheckAndThrowJsonExceptionIfNeeded(VoWorkItem voWorkItem) =>
voWorkItem.IsTheUnderlyingAValueType ? string.Empty
: $$"""
ThrowJsonExceptionWhenNull(value);
""";

public string GenerateAnyAttributes(TypeDeclarationSyntax tds, VoWorkItem item)
{
if (!item.Config.Conversions.HasFlag(Vogen.Conversions.SystemTextJson))
Expand Down Expand Up @@ -32,9 +75,9 @@ public string GenerateAnyBody(TypeDeclarationSyntax tds, VoWorkItem item)
{
allowNullReferences = false;
}

}

code = allowNullReferences ? CodeSections.CutSection(code, "__HANDLE_NULL__") : CodeSections.KeepSection(code, "__HANDLE_NULL__");

if (code.Contains("__NORMAL__"))
Expand All @@ -48,6 +91,8 @@ public string GenerateAnyBody(TypeDeclarationSyntax tds, VoWorkItem item)
code = CodeSections.KeepSection(code, keepCut.keep);
}

code = code.Replace("DESERIALIZEJSONMETHOD", GenerateDeserializeJsonMethod(item));

code = code.Replace("VOTYPE", item.VoTypeName);
code = code.Replace("VOUNDERLYINGTYPE", item.UnderlyingTypeFullName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
/// </summary>
public class VOTYPESystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<VOTYPE>
{
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
public override VOTYPE Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
var primitive = global::System.Text.Json.JsonSerializer.Deserialize<VOUNDERLYINGTYPE>(ref reader, options);
return VOTYPE.__Deserialize(primitive);
return DeserializeJson(primitive);
}

public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
Expand All @@ -22,12 +22,13 @@ public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value,
public override VOTYPE ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
var primitive = global::System.Text.Json.JsonSerializer.Deserialize<VOUNDERLYINGTYPE>(ref reader, options);
return VOTYPE.__Deserialize(primitive);
return DeserializeJson(primitive);
}

public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
{
writer.WritePropertyName(global::System.Text.Json.JsonSerializer.Serialize(value.Value));
}
#endif
#endif
DESERIALIZEJSONMETHOD
}
13 changes: 7 additions & 6 deletions src/Vogen/Templates/Boolean/Boolean_SystemTextJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
/// </summary>
public class VOTYPESystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<VOTYPE>
{
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
public override VOTYPE Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return VOTYPE.__Deserialize(reader.GetBoolean());
return DeserializeJson(reader.GetBoolean());
}

public override void Write(global::System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
Expand All @@ -20,12 +20,13 @@ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, VOTYP
#if NET6_0_OR_GREATER
public override VOTYPE ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return VOTYPE.__Deserialize(bool.Parse(reader.GetString()));
return DeserializeJson(bool.Parse(reader.GetString()));
}

public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
{
writer.WritePropertyName(value.Value.ToString());
}
#endif
#endif
DESERIALIZEJSONMETHOD
}
17 changes: 9 additions & 8 deletions src/Vogen/Templates/Byte/Byte_SystemTextJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
/// </summary>
public class VOTYPESystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<VOTYPE>
{
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
public override VOTYPE Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
#if NET5_0_OR_GREATER
__NORMAL__ return VOTYPE.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Byte>)options.GetTypeInfo(typeof(global::System.Byte))));
__NORMAL__ return DeserializeJson(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::System.Byte>)options.GetTypeInfo(typeof(global::System.Byte))));
#else
__NORMAL__ return VOTYPE.__Deserialize(reader.GetByte());
__NORMAL__ return DeserializeJson(reader.GetByte());
#endif
__STRING__ return VOTYPE.__Deserialize(global::System.Byte.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture));
__STRING__ return DeserializeJson(global::System.Byte.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture));
}

public override void Write(global::System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
Expand All @@ -31,12 +31,13 @@ public override void Write(global::System.Text.Json.Utf8JsonWriter writer, VOTYP
#if NET6_0_OR_GREATER
public override VOTYPE ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return VOTYPE.__Deserialize(global::System.Byte.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture));
return DeserializeJson(global::System.Byte.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture));
}

public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
{
writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture));
}
#endif
#endif
DESERIALIZEJSONMETHOD
}
13 changes: 7 additions & 6 deletions src/Vogen/Templates/Char/Char_SystemTextJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
/// </summary>
public class VOTYPESystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<VOTYPE>
{
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
public override VOTYPE Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
var s = reader.GetString();

return VOTYPE.__Deserialize(s[0]);
return DeserializeJson(s[0]);
}

public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
Expand All @@ -23,12 +23,13 @@ public override VOTYPE ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonR
{
var s = reader.GetString();

return VOTYPE.__Deserialize(s[0]);
return DeserializeJson(s[0]);
}

public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
{
writer.WritePropertyName(value.Value.ToString());
}
#endif
#endif
DESERIALIZEJSONMETHOD
}
12 changes: 7 additions & 5 deletions src/Vogen/Templates/DateOnly/DateOnly_SystemTextJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
/// </summary>
public class VOTYPESystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<VOTYPE>
{
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
public override VOTYPE Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return new VOTYPE(global::System.DateOnly.ParseExact(reader.GetString(), "yyyy-MM-dd", global::System.Globalization.CultureInfo.InvariantCulture));
return DeserializeJson(global::System.DateOnly.ParseExact(reader.GetString(), "yyyy-MM-dd", global::System.Globalization.CultureInfo.InvariantCulture));
}

public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
Expand All @@ -19,13 +19,15 @@ public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value,

public override VOTYPE ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return new VOTYPE(global::System.DateOnly.ParseExact(reader.GetString(), "yyyy-MM-dd", global::System.Globalization.CultureInfo.InvariantCulture));
return DeserializeJson(global::System.DateOnly.ParseExact(reader.GetString(), "yyyy-MM-dd", global::System.Globalization.CultureInfo.InvariantCulture));
}

public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
{
writer.WritePropertyName(value.Value.ToString("yyyy-MM-dd", global::System.Globalization.CultureInfo.InvariantCulture));
}

DESERIALIZEJSONMETHOD
}
#endif

13 changes: 7 additions & 6 deletions src/Vogen/Templates/DateTime/DateTime_SystemTextJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
/// </summary>
public class VOTYPESystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<VOTYPE>
{
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
public override VOTYPE Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return VOTYPE.__Deserialize(reader.GetDateTime().ToUniversalTime());
return DeserializeJson(reader.GetDateTime().ToUniversalTime());
}

public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
Expand All @@ -22,12 +22,13 @@ public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value,
/// </summary>
public override VOTYPE ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return VOTYPE.__Deserialize(global::System.DateTime.ParseExact(reader.GetString(), "O", global::System.Globalization.CultureInfo.InvariantCulture, global::System.Globalization.DateTimeStyles.RoundtripKind));
return DeserializeJson(global::System.DateTime.ParseExact(reader.GetString(), "O", global::System.Globalization.CultureInfo.InvariantCulture, global::System.Globalization.DateTimeStyles.RoundtripKind));
}

public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
{
writer.WritePropertyName(value.Value.ToUniversalTime().ToString("O", global::System.Globalization.CultureInfo.InvariantCulture));
}
#endif
#endif
DESERIALIZEJSONMETHOD
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
/// </summary>
public class VOTYPESystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter<VOTYPE>
{
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
__HANDLE_NULL__ #if NET5_0_OR_GREATER
__HANDLE_NULL__ public override bool HandleNull => true;
__HANDLE_NULL__ #endif
public override VOTYPE Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return VOTYPE.__Deserialize(reader.GetDateTimeOffset());
return DeserializeJson(reader.GetDateTimeOffset());
}

public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
Expand All @@ -20,12 +20,13 @@ public override void Write(System.Text.Json.Utf8JsonWriter writer, VOTYPE value,
#if NET6_0_OR_GREATER
public override VOTYPE ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
{
return VOTYPE.__Deserialize(global::System.DateTimeOffset.ParseExact(reader.GetString(), "O", global::System.Globalization.CultureInfo.InvariantCulture));
return DeserializeJson(global::System.DateTimeOffset.ParseExact(reader.GetString(), "O", global::System.Globalization.CultureInfo.InvariantCulture));
}

public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, VOTYPE value, global::System.Text.Json.JsonSerializerOptions options)
{
writer.WritePropertyName(value.Value.ToString("O"));
}
#endif
#endif
DESERIALIZEJSONMETHOD
}
Loading
Loading