Bugfix/#1 parsing failes due to price ifnromation scheme changes #2

Merged
Serraniel merged 3 commits from bugfix/#1-parsing-failes-due-to-price-ifnromation-scheme-changes into main 2023-03-24 18:12:40 +01:00
4 changed files with 50 additions and 113 deletions

View file

@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using JpnCardsPokemon.Sdk.Utils.JsonConverter;
namespace JpnCardsPokemon.Sdk.Api;
@ -64,7 +63,6 @@ public class Card
/// A list of known prices for this card.
/// </summary>
/// <remarks>May contain entries from different sellers, versions and conditions.</remarks>
[JsonConverter(typeof(CardPricesJsonConverter))]
public IEnumerable<CardPrice>? Prices { get; set; }
/// <summary>

View file

@ -1,5 +1,6 @@
using System;
using System.Text.Json.Serialization;
using JpnCardsPokemon.Sdk.Utils.JsonConverter;
namespace JpnCardsPokemon.Sdk.Api;
@ -12,6 +13,7 @@ public class CardPrice
/// Specifies the card version. Almost always will be 'Regular' but may contain other versions like 'Reverse Holo',
/// etc.
/// </summary>
[JsonPropertyName("variant")]
public string? Version { get; set; }
/// <summary>
@ -37,6 +39,7 @@ public class CardPrice
/// Date when the price information was updated last.
/// </summary>
[JsonPropertyName("dateUpdated")]
[JsonConverter(typeof(CustomDateTimeConverter))]
public DateTime? UpdatedDate { get; set; }
/// <summary>
@ -48,5 +51,6 @@ public class CardPrice
/// <summary>
/// Name of the seller who is listing the card.
/// </summary>
[JsonPropertyName("vendor")]
public string? Seller { get; set; }
}

View file

@ -1,111 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using JpnCardsPokemon.Sdk.Api;
namespace JpnCardsPokemon.Sdk.Utils.JsonConverter;
internal class CardPricesJsonConverter : JsonConverter<IEnumerable<CardPrice>>
{
public override IEnumerable<CardPrice> Read(ref Utf8JsonReader reader, Type typeToConvert,
JsonSerializerOptions options)
{
var resultBucket = new List<CardPrice>();
// read sellers
while (reader.Read())
{
// Finished parsing?
if (reader.TokenType == JsonTokenType.EndArray)
break;
if (reader.TokenType != JsonTokenType.PropertyName) continue;
var sellerName = reader.GetString();
// Versions
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndArray)
break;
// Version, usually "Regular"
if (reader.TokenType != JsonTokenType.PropertyName) continue;
var cardVersion = reader.GetString();
// Conditions
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject) break;
if (reader.TokenType != JsonTokenType.PropertyName) continue;
var condition = reader.GetString();
var cardPrice = new CardPrice
{
Seller = sellerName,
Version = cardVersion,
Condition = condition
};
var propertyName = string.Empty;
// Final price properties
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject) break;
if (reader.TokenType == JsonTokenType.PropertyName)
{
propertyName = reader.GetString();
}
else
{
// search correct property in object
if (string.IsNullOrEmpty(propertyName)) continue;
var property = cardPrice.GetType().GetProperty(propertyName) ?? cardPrice
.GetType().GetProperties().FirstOrDefault(p =>
p.GetCustomAttributes(typeof(JsonPropertyNameAttribute), true)
.Cast<JsonPropertyNameAttribute>()
.Any(a => a.Name.Equals(propertyName,
StringComparison.InvariantCultureIgnoreCase)));
if (property != null)
{
object? value = null;
var propertyType = property.PropertyType;
if (propertyType == typeof(string))
value = reader.GetString();
else if (propertyType == typeof(decimal))
value = reader.GetDecimal();
else if (propertyType == typeof(DateTime?))
if (DateTime.TryParseExact(reader.GetString(), "MM/dd/yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt))
value = dt;
property.SetValue(cardPrice, value);
}
propertyName = string.Empty;
}
}
// add card to bucket
resultBucket.Add(cardPrice);
}
}
}
return resultBucket;
}
public override void Write(Utf8JsonWriter writer, IEnumerable<CardPrice> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace JpnCardsPokemon.Sdk.Utils.JsonConverter
{
internal class CustomDateTimeConverter : JsonConverter<DateTime?>
{
private readonly string _dateTimeFormat = "MM/dd/yyyy";
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.Null:
return null;
case JsonTokenType.String:
{
var dateString = reader.GetString();
if (DateTime.TryParseExact(dateString, _dateTimeFormat, null, System.Globalization.DateTimeStyles.None, out var dateTime))
{
return dateTime;
}
break;
}
default:
throw new JsonException($"Cannot convert {reader.GetString()} to DateTime.");
}
throw new JsonException($"Cannot convert {reader.GetString()} to DateTime.");
}
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
{
if (value.HasValue)
{
writer.WriteStringValue(value.Value.ToString(_dateTimeFormat));
}
else
{
writer.WriteNullValue();
}
}
}
}