Skip to content

Commit 5a0326c

Browse files
committed
Bug fix: CargoRecordConverter.DeserializeNullable* methods should support quoted numbers.
1 parent 4e7d07d commit 5a0326c

File tree

2 files changed

+27
-24
lines changed

2 files changed

+27
-24
lines changed

UnitTestProject1/Tests/CargoTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public async Task LinqToCargoDateTimeTest1()
7777
// Call .AsAsyncEnumerable to ensure we use async Linq call.
7878
var records = await q.AsAsyncEnumerable().ToListAsync();
7979
ShallowTrace(records);
80-
Assert.Equal(99, records.Count);
80+
Assert.Equal(100, records.Count);
8181
Assert.All(records, r => Assert.Equal(r.ReleaseDate?.Year, r.Year));
8282
Assert.All(records, r => Assert.InRange(r.Year, 2019, 2020));
8383
}

WikiClientLibrary.Cargo/Linq/CargoRecordConverter.cs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ private static readonly MethodInfo dictTryGetValue
4040
[return: NotNullIfNotNull("value")]
4141
private static IList<T>? DeserializeCollection<T>(JsonNode? value, string separator)
4242
{
43-
var values = (string)value;
43+
var values = (string?)value;
4444
if (values == null) return default;
4545
if (values.Length == 0) return Array.Empty<T>();
46-
return values.Split(new[] { separator }, StringSplitOptions.None)
46+
return values.Split([separator], StringSplitOptions.None)
4747
.Select(i => (T)Convert.ChangeType(i, typeof(T), CultureInfo.InvariantCulture))
4848
.ToList()!;
4949
}
@@ -54,7 +54,7 @@ private static readonly MethodInfo dictTryGetValue
5454
var values = (string?)value;
5555
if (values == null) return default;
5656
if (values.Length == 0) return Array.Empty<string>();
57-
var result = values.Split(new[] { separator }, StringSplitOptions.None);
57+
var result = values.Split([separator], StringSplitOptions.None);
5858
for (int i = 0; i < result.Length; i++)
5959
result[i] = result[i].Trim();
6060
return result;
@@ -96,7 +96,7 @@ public virtual object DeserializeRecord(IReadOnlyDictionary<MemberInfo, JsonNode
9696
var builder = new DynamicMethod(
9797
typeof(CargoRecordConverter) + "$DeserializeRecordImpl[" + modelType + "]",
9898
modelType,
99-
new[] { typeof(IReadOnlyDictionary<string, JsonNode>) },
99+
[typeof(IReadOnlyDictionary<string, JsonNode>)],
100100
typeof(CargoRecordConverter)
101101
);
102102
var gen = builder.GetILGenerator();
@@ -181,7 +181,7 @@ public static MethodInfo GetValueDeserializer(Type valueType)
181181

182182
public static T? DeserializeValue<T>(JsonNode? value) => value == null ? default : value.Deserialize<T>();
183183

184-
public static bool IsNullableNull(JsonNode token)
184+
public static bool IsNullableNull([NotNullWhen(false)] JsonNode? token)
185185
{
186186
if (token == null) return true;
187187
if (token is not JsonValue value) return false;
@@ -202,47 +202,50 @@ public static bool IsNullableNull(JsonNode token)
202202

203203
public static string? DeserializeString(JsonNode value) => (string?)value;
204204

205-
private static Exception CreateInvalidCastException(Type targetType)
206-
=> new InvalidOperationException($"Cannot cast the JSON node into {targetType}.");
205+
private static Exception CreateInvalidCastException(Type targetType, string jsonPath)
206+
=> new InvalidOperationException($"Cannot cast the JSON node into {targetType}. JSON path: {jsonPath}");
207+
208+
private static Exception CreateInvalidCastException(Type targetType, JsonNode node)
209+
=> CreateInvalidCastException(targetType, node.GetPath());
207210

208211
public static int DeserializeInt32(JsonNode node)
209212
{
210213
var value = node.AsValue();
211214
if (value.TryGetValue(out int i32)) return i32;
212215
if (value.TryGetValue(out string? str)) return Convert.ToInt32(str);
213-
throw CreateInvalidCastException(typeof(int));
216+
throw CreateInvalidCastException(typeof(int), node);
214217
}
215218

216219
public static long DeserializeInt64(JsonNode node)
217220
{
218221
var value = node.AsValue();
219222
if (value.TryGetValue(out long i64)) return i64;
220223
if (value.TryGetValue(out string? str)) return Convert.ToInt64(str);
221-
throw CreateInvalidCastException(typeof(long));
224+
throw CreateInvalidCastException(typeof(long), node);
222225
}
223226

224227
public static float DeserializeFloat(JsonNode node)
225228
{
226229
var value = node.AsValue();
227230
if (value.TryGetValue(out float f)) return f;
228231
if (value.TryGetValue(out string? str)) return Convert.ToSingle(str);
229-
throw CreateInvalidCastException(typeof(float));
232+
throw CreateInvalidCastException(typeof(float), node);
230233
}
231234

232235
public static double DeserializeDouble(JsonNode node)
233236
{
234237
var value = node.AsValue();
235238
if (value.TryGetValue(out double d)) return d;
236239
if (value.TryGetValue(out string? str)) return Convert.ToDouble(str);
237-
throw CreateInvalidCastException(typeof(double));
240+
throw CreateInvalidCastException(typeof(double), node);
238241
}
239242

240243
public static decimal DeserializeDecimal(JsonNode node)
241244
{
242245
var value = node.AsValue();
243246
if (value.TryGetValue(out decimal dec)) return dec;
244247
if (value.TryGetValue(out string? str)) return Convert.ToDecimal(str);
245-
throw CreateInvalidCastException(typeof(decimal));
248+
throw CreateInvalidCastException(typeof(decimal), node);
246249
}
247250

248251
public static bool DeserializeBoolean(JsonNode node)
@@ -271,33 +274,33 @@ public static DateTime DeserializeDateTime(JsonNode node)
271274
var value = node.AsValue();
272275
if (value.TryGetValue(out DateTime dt)) return dt;
273276
if (value.TryGetValue(out string? str)) return Convert.ToDateTime(str);
274-
throw CreateInvalidCastException(typeof(DateTime));
277+
throw CreateInvalidCastException(typeof(DateTime), node);
275278
}
276279

277280
public static DateTimeOffset DeserializeDateTimeOffset(JsonNode node)
278281
{
279282
var value = node.AsValue();
280283
if (value.TryGetValue(out DateTimeOffset dto)) return dto;
281284
if (value.TryGetValue(out string? str)) return DateTimeOffset.Parse(str);
282-
throw CreateInvalidCastException(typeof(DateTimeOffset));
285+
throw CreateInvalidCastException(typeof(DateTimeOffset), node);
283286
}
284287

285-
public static int? DeserializeNullableInt32(JsonNode value) => IsNullableNull(value) ? (int?)null : (int)value;
288+
public static int? DeserializeNullableInt32(JsonNode? value) => IsNullableNull(value) ? null : DeserializeInt32(value);
286289

287-
public static long? DeserializeNullableInt64(JsonNode value) => IsNullableNull(value) ? (long?)null : (long)value;
290+
public static long? DeserializeNullableInt64(JsonNode? value) => IsNullableNull(value) ? null : DeserializeInt64(value);
288291

289-
public static float? DeserializeNullableFloat(JsonNode value) => IsNullableNull(value) ? (float?)null : (float)value;
292+
public static float? DeserializeNullableFloat(JsonNode? value) => IsNullableNull(value) ? null : DeserializeFloat(value);
290293

291-
public static double? DeserializeNullableDouble(JsonNode value) => IsNullableNull(value) ? (double?)null : (double)value;
294+
public static double? DeserializeNullableDouble(JsonNode? value) => IsNullableNull(value) ? null : DeserializeDouble(value);
292295

293-
public static decimal? DeserializeNullableDecimal(JsonNode value) => IsNullableNull(value) ? (decimal?)null : (decimal)value;
296+
public static decimal? DeserializeNullableDecimal(JsonNode? value) => IsNullableNull(value) ? null : DeserializeDecimal(value);
294297

295-
public static bool? DeserializeNullableBoolean(JsonNode value) => IsNullableNull(value) ? (bool?)null : DeserializeBoolean(value);
298+
public static bool? DeserializeNullableBoolean(JsonNode? value) => IsNullableNull(value) ? null : DeserializeBoolean(value);
296299

297-
public static DateTime? DeserializeNullableDateTime(JsonNode value) => IsNullableNull(value) ? (DateTime?)null : (DateTime)value;
300+
public static DateTime? DeserializeNullableDateTime(JsonNode? value) => IsNullableNull(value) ? null : DeserializeDateTime(value);
298301

299-
public static DateTimeOffset? DeserializeNullableDateTimeOffset(JsonNode value)
300-
=> IsNullableNull(value) ? (DateTimeOffset?)null : (DateTimeOffset)value;
302+
public static DateTimeOffset? DeserializeNullableDateTimeOffset(JsonNode? value)
303+
=> IsNullableNull(value) ? null : DeserializeDateTimeOffset(value);
301304

302305
}
303306

0 commit comments

Comments
 (0)