Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Globalization;

namespace Yllibed.TenantCloudClient.HttpMessages;

/// <summary>
/// Reads a JSON value that TenantCloud sometimes serializes as a string and
/// sometimes as a number (observed on <c>property_status</c>) into a string.
/// Writes back out as a string.
/// </summary>
public class JsonFlexibleStringConverter : JsonConverter<string?>
{
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
return reader.GetString();
case JsonTokenType.Number:
return reader.TryGetInt64(out var l)
? l.ToString(CultureInfo.InvariantCulture)
: reader.GetDouble().ToString(CultureInfo.InvariantCulture);
case JsonTokenType.True:
return "true";
case JsonTokenType.False:
return "false";
case JsonTokenType.Null:
return null;
default:
throw new NotSupportedException($"Type {reader.TokenType} not supported for flexible string");
}
}

public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
}
else
{
writer.WriteStringValue(value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Globalization;

namespace Yllibed.TenantCloudClient.HttpMessages;

/// <summary>
/// Reads a JSON decimal value that may also legitimately be <c>null</c> or a
/// numeric string (observed on unit <c>price</c>). Returns <c>null</c> for a
/// JSON null and parses strings tolerantly.
/// </summary>
public class JsonNullableDecimalConverter : JsonConverter<decimal?>
{
public override decimal? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.Null:
return null;
case JsonTokenType.Number:
return reader.GetDecimal();
case JsonTokenType.String:
var str = reader.GetString();
return string.IsNullOrWhiteSpace(str) ? null : decimal.Parse(str, CultureInfo.InvariantCulture);
default:
throw new NotSupportedException($"Type {reader.TokenType} not supported for nullable decimal");
}
}

public override void Write(Utf8JsonWriter writer, decimal? value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
}
else
{
writer.WriteNumberValue(value.Value);
}
}
}
1 change: 1 addition & 0 deletions src/Yllibed.TenantCloudClient/HttpMessages/TcProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class TcProperty : IHasId
public string? CityAddress { get; set; }

[JsonPropertyName("property_status")]
[JsonConverter(typeof(JsonFlexibleStringConverter))]
public string? Status { get; set; }

public string Address => string.Format(CultureInfo.InvariantCulture, "{0} {1}", Address1, CityAddress);
Expand Down
3 changes: 2 additions & 1 deletion src/Yllibed.TenantCloudClient/HttpMessages/TcUnit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public class TcUnit : IHasId

public string? Description { get; set; }

public decimal Price { get; set; }
[JsonConverter(typeof(JsonNullableDecimalConverter))]
public decimal? Price { get; set; }

[JsonPropertyName("is_rented")]
public bool IsRented { get; set; }
Expand Down