Skip to content

Commit

Permalink
fix: Fixed issues with AllOf polymorphism.
Browse files Browse the repository at this point in the history
  • Loading branch information
HavenDV committed Dec 22, 2024
1 parent ff2004d commit 5bdd949
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 36 deletions.
6 changes: 6 additions & 0 deletions src/libs/AutoSDK/Models/TypeData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace AutoSDK.Models;
public readonly record struct TypeData(
string CSharpTypeRaw,
bool CSharpTypeNullability,
bool IsBaseClass,
bool IsDerivedClass,
bool IsArray,
bool IsNullable,
bool IsEnum,
Expand All @@ -30,6 +32,8 @@ public readonly record struct TypeData(
public static TypeData Default => new(
CSharpTypeRaw: string.Empty,
CSharpTypeNullability: false,
IsBaseClass: false,
IsDerivedClass: false,
IsArray: false,
IsNullable: false,
IsEnum: false,
Expand Down Expand Up @@ -161,6 +165,8 @@ Default with
return new TypeData(
CSharpTypeRaw: type,
CSharpTypeNullability: GetCSharpNullability(context),
IsBaseClass: context.IsBaseClass,
IsDerivedClass: context.IsDerivedClass,
IsValueType: ContextIsValueType(context),
IsNullable: context.Schema.Nullable,
IsArray: context.Schema.IsArray(),
Expand Down
10 changes: 6 additions & 4 deletions src/libs/AutoSDK/Serialization/Json/SystemTextJsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,12 @@ public string GenerateSerializeCall(TypeData type, string jsonSerializerContext)

public string GenerateDeserializeCall(string variableName, TypeData type, string jsonSerializerContext)
{
var typeToDeserializeIfRequired = type.IsDerivedClass || type.IsBaseClass ? $"<{type.CSharpTypeWithoutNullability}>" : "";
if (type.CSharpType.StartsWith($"global::{type.Settings.Namespace}", StringComparison.Ordinal))
{
return string.IsNullOrWhiteSpace(jsonSerializerContext)
? $"{type.CSharpTypeWithoutNullability}.FromJson({variableName}, JsonSerializerOptions)"
: $"{type.CSharpTypeWithoutNullability}.FromJson({variableName}, JsonSerializerContext)";
? $"{type.CSharpTypeWithoutNullability}.FromJson{typeToDeserializeIfRequired}({variableName}, JsonSerializerOptions)"
: $"{type.CSharpTypeWithoutNullability}.FromJson{typeToDeserializeIfRequired}({variableName}, JsonSerializerContext)";
}

return string.IsNullOrWhiteSpace(jsonSerializerContext)
Expand All @@ -121,11 +122,12 @@ public string GenerateDeserializeCall(string variableName, TypeData type, string

public string GenerateDeserializeFromStreamCall(string variableName, TypeData type, string jsonSerializerContext)
{
var typeToDeserializeIfRequired = type.IsDerivedClass || type.IsBaseClass ? $"<{type.CSharpTypeWithoutNullability}>" : "";
if (type.CSharpType.StartsWith($"global::{type.Settings.Namespace}", StringComparison.Ordinal))
{
return string.IsNullOrWhiteSpace(jsonSerializerContext)
? $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync({variableName}, JsonSerializerOptions).ConfigureAwait(false)"
: $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync({variableName}, JsonSerializerContext).ConfigureAwait(false)";
? $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync{typeToDeserializeIfRequired}({variableName}, JsonSerializerOptions).ConfigureAwait(false)"
: $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync{typeToDeserializeIfRequired}({variableName}, JsonSerializerContext).ConfigureAwait(false)";
}

return string.IsNullOrWhiteSpace(jsonSerializerContext)
Expand Down
53 changes: 34 additions & 19 deletions src/libs/AutoSDK/Sources/Sources.Models.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public static string GenerateModelFromToJsonMethods(
var modifiers = isValueType
? "readonly partial struct"
: $"{(isBaseClass ? "" : "sealed ")}partial class";
var isDerivedClass = !string.IsNullOrWhiteSpace(baseClassName);

return settings.JsonSerializerType == JsonSerializerType.SystemTextJson
? @$"#nullable enable
Expand All @@ -72,7 +71,7 @@ public string ToJson(
{{
return global::System.Text.Json.JsonSerializer.Serialize(
this,
{(isDerivedClass ? $"typeof({baseClassName})" : "this.GetType()")},
{(isBaseClass ? $"typeof({className})" : "this.GetType()")},
jsonSerializerContext);
}}
Expand All @@ -86,67 +85,83 @@ public string ToJson(
{{
return global::System.Text.Json.JsonSerializer.Serialize(
this,
{(isDerivedClass ? $"typeof({baseClassName})," : string.Empty)}
{(isBaseClass ? $"typeof({className})," : string.Empty)}
jsonSerializerOptions);
}}
{"Deserializes a JSON string using the provided JsonSerializerContext.".ToXmlDocumentationSummary(level: 8)}
public static {typeName}? FromJson{(isDerivedClass ? "<T>" : string.Empty)}(
public static {(isBaseClass ? "T" : typeName)}? FromJson{(isBaseClass ? "<T>" : string.Empty)}(
string json,
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
{(isBaseClass ? $"where T : {className}" : string.Empty)}
{{
return global::System.Text.Json.JsonSerializer.Deserialize(
json,
typeof({(isDerivedClass ? baseClassName : typeName)}),
jsonSerializerContext) as {(isDerivedClass ? "T" : typeName)}{(isValueType ? "?" : "")};
typeof({(isBaseClass ? className : typeName)}),
jsonSerializerContext) as {(isBaseClass ? "T" : typeName)}{(isValueType ? "?" : "")};
}}
{"Deserializes a JSON string using the provided JsonSerializerOptions.".ToXmlDocumentationSummary(level: 8)}
#if NET8_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode(""JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved."")]
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode(""JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications."")]
#endif
public static {typeName}? FromJson{(isDerivedClass ? "<T>" : string.Empty)}(
public static {(isBaseClass ? "T" : typeName)}? FromJson{(isBaseClass ? "<T>" : string.Empty)}(
string json,
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
{(isBaseClass ? $"where T : {className}" : string.Empty)}
{{
return global::System.Text.Json.JsonSerializer.Deserialize<{(isDerivedClass ? baseClassName : typeName)}>(
return global::System.Text.Json.JsonSerializer.Deserialize<{(isBaseClass ? className : typeName)}>(
json,
jsonSerializerOptions){(isDerivedClass ? " as T" : string.Empty)};
jsonSerializerOptions){(isBaseClass ? " as T" : string.Empty)};
}}
/// <summary>
/// Deserializes a JSON stream using the provided JsonSerializerContext.
/// </summary>
public static async global::System.Threading.Tasks.ValueTask<{typeName}?> FromJsonStreamAsync{(isDerivedClass ? "<T>" : string.Empty)}(
public static async global::System.Threading.Tasks.ValueTask<{(isBaseClass ? "T?" : $"{typeName}?")}> FromJsonStreamAsync{(isBaseClass ? "<T>" : string.Empty)}(
global::System.IO.Stream jsonStream,
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
{(isBaseClass ? $"where T : {className}" : string.Empty)}
{{
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync(
jsonStream,
typeof({(isDerivedClass ? baseClassName : typeName)}),
jsonSerializerContext).ConfigureAwait(false)) as {(isDerivedClass ? "T" : typeName)}{(isValueType ? "?" : "")};
typeof({(isBaseClass ? className : typeName)}),
jsonSerializerContext).ConfigureAwait(false)) as {(isBaseClass ? "T" : typeName)}{(isValueType ? "?" : "")};
}}
{(isBaseClass ? $@"
/// <summary>
/// Deserializes a JSON stream using the provided JsonSerializerOptions.
/// </summary>
#if NET8_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode(""JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved."")]
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode(""JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications."")]
#endif
public static global::System.Threading.Tasks.ValueTask<{typeName}?> FromJsonStreamAsync{(isDerivedClass ? "<T>" : string.Empty)}(
public static async global::System.Threading.Tasks.ValueTask<T?> FromJsonStreamAsync<T>(
global::System.IO.Stream jsonStream,
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
where T : {className}
{{
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync<{className}?>(
jsonStream,
jsonSerializerOptions).ConfigureAwait(false)) as T{(isValueType ? "?" : "")};
}}" : $@"
/// <summary>
/// Deserializes a JSON stream using the provided JsonSerializerOptions.
/// </summary>
#if NET8_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode(""JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved."")]
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode(""JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications."")]
#endif
public static global::System.Threading.Tasks.ValueTask<{typeName}?> FromJsonStreamAsync(
global::System.IO.Stream jsonStream,
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
{{
return global::System.Text.Json.JsonSerializer.DeserializeAsync<{typeName}?>(
jsonStream,
jsonSerializerOptions){(isDerivedClass ? " as T" : string.Empty)};
}}
jsonSerializerOptions);
}}")}
}}
}}
".RemoveBlankLinesWhereOnlyWhitespaces()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public string ToJson(
{
return global::System.Text.Json.JsonSerializer.Serialize(
this,
this.GetType(),
typeof(ChatStreamEvent),
jsonSerializerContext);
}

Expand All @@ -29,20 +29,22 @@ public string ToJson(
{
return global::System.Text.Json.JsonSerializer.Serialize(
this,
typeof(ChatStreamEvent),
jsonSerializerOptions);
}

/// <summary>
/// Deserializes a JSON string using the provided JsonSerializerContext.
/// </summary>
public static global::G.ChatStreamEvent? FromJson(
public static T? FromJson<T>(
string json,
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
where T : ChatStreamEvent
{
return global::System.Text.Json.JsonSerializer.Deserialize(
json,
typeof(global::G.ChatStreamEvent),
jsonSerializerContext) as global::G.ChatStreamEvent;
typeof(ChatStreamEvent),
jsonSerializerContext) as T;
}

/// <summary>
Expand All @@ -52,26 +54,28 @@ public string ToJson(
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
#endif
public static global::G.ChatStreamEvent? FromJson(
public static T? FromJson<T>(
string json,
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
where T : ChatStreamEvent
{
return global::System.Text.Json.JsonSerializer.Deserialize<global::G.ChatStreamEvent>(
return global::System.Text.Json.JsonSerializer.Deserialize<ChatStreamEvent>(
json,
jsonSerializerOptions);
jsonSerializerOptions) as T;
}

/// <summary>
/// Deserializes a JSON stream using the provided JsonSerializerContext.
/// </summary>
public static async global::System.Threading.Tasks.ValueTask<global::G.ChatStreamEvent?> FromJsonStreamAsync(
public static async global::System.Threading.Tasks.ValueTask<T?> FromJsonStreamAsync<T>(
global::System.IO.Stream jsonStream,
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
where T : ChatStreamEvent
{
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync(
jsonStream,
typeof(global::G.ChatStreamEvent),
jsonSerializerContext).ConfigureAwait(false)) as global::G.ChatStreamEvent;
typeof(ChatStreamEvent),
jsonSerializerContext).ConfigureAwait(false)) as T;
}

/// <summary>
Expand All @@ -81,13 +85,14 @@ public string ToJson(
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
#endif
public static global::System.Threading.Tasks.ValueTask<global::G.ChatStreamEvent?> FromJsonStreamAsync(
public static async global::System.Threading.Tasks.ValueTask<T?> FromJsonStreamAsync<T>(
global::System.IO.Stream jsonStream,
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
where T : ChatStreamEvent
{
return global::System.Text.Json.JsonSerializer.DeserializeAsync<global::G.ChatStreamEvent?>(
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync<ChatStreamEvent?>(
jsonStream,
jsonSerializerOptions);
jsonSerializerOptions).ConfigureAwait(false)) as T;
}
}
}

0 comments on commit 5bdd949

Please sign in to comment.