Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion BO4E/ENUM/Verwendungszweck.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
using System;
using System.Runtime.Serialization;
using BO4E.meta.LenientConverters;

namespace BO4E.ENUM;

/// <summary>Verwendungungszweck der Werte Marktlokation</summary>
[System.Text.Json.Serialization.JsonConverter(
typeof(SystemTextVerwendungszweckStringEnumConverter)
)]
[Newtonsoft.Json.JsonConverter(typeof(NewtonsoftVerwendungszweckStringEnumConverter))]
public enum Verwendungszweck
{
/// <summary>Z84: Netznutzungsabrechnung</summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace BO4E.meta.LenientConverters;

/// <summary>
/// Converts a stringified single <see cref="BO4E.ENUM.Verwendungszweck"/>
/// to a <see cref="BO4E.COM.Verwendungszweck"/> which has the single enum value as member in <see cref="COM.Verwendungszweck.Zweck"/>
/// </summary>
/// /// <remarks><seealso cref="SystemTextVerwendungszweckEnumToComConverter"/></remarks>
public class NewtonsoftVerwendungszweckEnumToComConverter
: Newtonsoft.Json.JsonConverter<BO4E.COM.Verwendungszweck?>
{
/// <inheritdoc />
public override bool CanWrite => false;

/// <inheritdoc />
public override void WriteJson(
JsonWriter writer,
BO4E.COM.Verwendungszweck? value,
JsonSerializer serializer
)
{
throw new NotImplementedException(
"This converter is only intended to work with deserialization; Tests show that this alone is sufficient."
);
}

/// <inheritdoc />
public override BO4E.COM.Verwendungszweck? ReadJson(
JsonReader reader,
Type objectType,
BO4E.COM.Verwendungszweck? existingValue,
bool hasExistingValue,
JsonSerializer serializer
)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}

if (reader.TokenType == JsonToken.String)
{
var result = new BO4E.COM.Verwendungszweck
{
Marktrolle = ENUM.Marktrolle.LF,
Zweck = new List<ENUM.Verwendungszweck>(),
};
var stringValue = (string)reader.Value!;
// we don't want to interfere or re-add the famous and beloved NewtonsoftVerwendungszweckStringEnumConverter
stringValue = stringValue.Replace(
"MEHRMINDERMBENGENABRECHNUNG",
"MEHRMINDERMENGENABRECHNUNG"
);
result.Zweck.Add(
(BO4E.ENUM.Verwendungszweck)
Enum.Parse(typeof(BO4E.ENUM.Verwendungszweck), stringValue)
);
return result;
}

int? stringEnumConverterIndex = null;
foreach (var converter in serializer.Converters)
{
if (converter is NewtonsoftVerwendungszweckStringEnumConverter)
{
stringEnumConverterIndex = serializer.Converters.IndexOf(converter);
break;
}
}
int? thisConverterIndex =
serializer.Converters.IndexOf(this) == -1 ? null : serializer.Converters.IndexOf(this);

if (stringEnumConverterIndex == null)
{
serializer.Converters.Add(new NewtonsoftVerwendungszweckStringEnumConverter());
;
}
if (thisConverterIndex != null)
{
serializer.Converters.RemoveAt(thisConverterIndex.Value);
}
// Delegate to the default behavior for complex objects or other token types
var objectResult = JToken.ReadFrom(reader).ToObject<BO4E.COM.Verwendungszweck>(serializer);
if (thisConverterIndex != null)
{
serializer.Converters.Insert(thisConverterIndex.Value, this);
}
if (stringEnumConverterIndex == null)
{
serializer.Converters.RemoveAt(serializer.Converters.Count - 1);
}

return objectResult;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using BO4E.COM;
using JsonException = System.Text.Json.JsonException;
using JsonSerializer = System.Text.Json.JsonSerializer;

namespace BO4E.meta.LenientConverters;

/// <summary>
/// Converts a stringified single <see cref="BO4E.ENUM.Verwendungszweck"/>
/// to a <see cref="BO4E.COM.Verwendungszweck"/> which has the single enum value as member in <see cref="Verwendungszweck.Zweck"/>
/// </summary>
/// <remarks><seealso cref="NewtonsoftVerwendungszweckEnumToComConverter"/></remarks>
public class SystemTextVerwendungszweckEnumToComConverter
: System.Text.Json.Serialization.JsonConverter<Verwendungszweck?>
{
/// <inheritdoc />
public override Verwendungszweck? Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options
)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
if (reader.TokenType == JsonTokenType.String)
{
var result = new Verwendungszweck
{
Marktrolle = ENUM.Marktrolle.LF,
Zweck = new List<ENUM.Verwendungszweck>(),
};
string stringValue = reader.GetString()!;

// Adjust the string as per the Newtonsoft version
stringValue = stringValue.Replace(
"MEHRMINDERMBENGENABRECHNUNG",
"MEHRMINDERMENGENABRECHNUNG"
);

// Parse and add the enum value
if (Enum.TryParse<ENUM.Verwendungszweck>(stringValue, out var enumValue))
{
result.Zweck.Add(enumValue);
}
else
{
throw new JsonException($"Invalid Verwendungszweck value: {stringValue}");
}

return result;
}

// Delegate to the default deserialization behavior for Verwendungszweck
return JsonSerializer.Deserialize<Verwendungszweck>(
ref reader,
CloneJsonSerializerOptionsExceptThis(options)
);
}

private JsonSerializerOptions CloneJsonSerializerOptionsExceptThis(
JsonSerializerOptions options
)
{
var clonedOptions = new JsonSerializerOptions
{
AllowTrailingCommas = options.AllowTrailingCommas,
DefaultBufferSize = options.DefaultBufferSize,
DictionaryKeyPolicy = options.DictionaryKeyPolicy,
DefaultIgnoreCondition = options.DefaultIgnoreCondition,
IgnoreReadOnlyProperties = options.IgnoreReadOnlyProperties,
MaxDepth = options.MaxDepth,
PropertyNameCaseInsensitive = options.PropertyNameCaseInsensitive,
PropertyNamingPolicy = options.PropertyNamingPolicy,
ReadCommentHandling = options.ReadCommentHandling,
WriteIndented = options.WriteIndented,
};

foreach (var converter in options.Converters)
{
if (converter.GetType() == GetType())
{
// prevents stackoverflowexception
continue;
}
clonedOptions.Converters.Add(converter);
}
clonedOptions.Converters.Add(new SystemTextVerwendungszweckStringEnumConverter());
return clonedOptions;
}

/// <inheritdoc />
public override void Write(
Utf8JsonWriter writer,
Verwendungszweck? value,
JsonSerializerOptions options
)
{
JsonSerializer.Serialize(writer, value, CloneJsonSerializerOptionsExceptThis(options));
}
}
Loading
Loading