Skip to content

Commit bd76c96

Browse files
committed
Hand-craft IndexSettingsTimeSeriesConverter to handle out-of-range dates (#8873)
(cherry picked from commit 90fc7c9)
1 parent 87ce448 commit bd76c96

4 files changed

Lines changed: 87 additions & 73 deletions

File tree

src/Elastic.Clients.Elasticsearch/_Generated/Types/IndexManagement/IndexSettingsTimeSeries.Converters.g.cs

Lines changed: 0 additions & 72 deletions
This file was deleted.

src/Elastic.Clients.Elasticsearch/_Generated/Types/IndexManagement/IndexSettingsTimeSeries.g.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
namespace Elastic.Clients.Elasticsearch.IndexManagement;
2525

26-
[System.Text.Json.Serialization.JsonConverter(typeof(Elastic.Clients.Elasticsearch.IndexManagement.Json.IndexSettingsTimeSeriesConverter))]
2726
public sealed partial class IndexSettingsTimeSeries
2827
{
2928
public IndexSettingsTimeSeries()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Text.Json.Serialization;
6+
7+
namespace Elastic.Clients.Elasticsearch.IndexManagement;
8+
9+
[JsonConverter(typeof(Json.IndexSettingsTimeSeriesConverter))]
10+
public sealed partial class IndexSettingsTimeSeries
11+
{
12+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Text.Json;
7+
using System.Text.Json.Serialization;
8+
9+
using Elastic.Clients.Elasticsearch.Serialization;
10+
11+
namespace Elastic.Clients.Elasticsearch.IndexManagement.Json;
12+
13+
public sealed class IndexSettingsTimeSeriesConverter : JsonConverter<IndexSettingsTimeSeries>
14+
{
15+
private static readonly JsonEncodedText PropEndTime = JsonEncodedText.Encode("end_time"u8);
16+
private static readonly JsonEncodedText PropStartTime = JsonEncodedText.Encode("start_time"u8);
17+
18+
public override IndexSettingsTimeSeries Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
19+
{
20+
reader.ValidateToken(JsonTokenType.StartObject);
21+
LocalJsonValue<DateTimeOffset?> propEndTime = default;
22+
LocalJsonValue<DateTimeOffset?> propStartTime = default;
23+
while (reader.Read() && reader.TokenType is JsonTokenType.PropertyName)
24+
{
25+
if (propEndTime.TryReadProperty(ref reader, options, PropEndTime, static DateTimeOffset? (ref Utf8JsonReader r, JsonSerializerOptions o) => ReadDateTime(ref r, o)))
26+
{
27+
continue;
28+
}
29+
30+
if (propStartTime.TryReadProperty(ref reader, options, PropStartTime, static DateTimeOffset? (ref Utf8JsonReader r, JsonSerializerOptions o) => ReadDateTime(ref r, o)))
31+
{
32+
continue;
33+
}
34+
35+
if (options.UnmappedMemberHandling is JsonUnmappedMemberHandling.Skip)
36+
{
37+
reader.SafeSkip();
38+
continue;
39+
}
40+
41+
throw new JsonException($"Unknown JSON property '{reader.GetString()}' for type '{typeToConvert.Name}'.");
42+
}
43+
44+
reader.ValidateToken(JsonTokenType.EndObject);
45+
return new IndexSettingsTimeSeries(JsonConstructorSentinel.Instance)
46+
{
47+
EndTime = propEndTime.Value,
48+
StartTime = propStartTime.Value
49+
};
50+
}
51+
52+
public override void Write(Utf8JsonWriter writer, IndexSettingsTimeSeries value, JsonSerializerOptions options)
53+
{
54+
writer.WriteStartObject();
55+
writer.WriteProperty(options, PropEndTime, value.EndTime, null, static (Utf8JsonWriter w, JsonSerializerOptions o, DateTimeOffset? v) => w.WriteNullableValueEx<DateTimeOffset>(o, v, typeof(DateTimeMarker)));
56+
writer.WriteProperty(options, PropStartTime, value.StartTime, null, static (Utf8JsonWriter w, JsonSerializerOptions o, DateTimeOffset? v) => w.WriteNullableValueEx<DateTimeOffset>(o, v, typeof(DateTimeMarker)));
57+
writer.WriteEndObject();
58+
}
59+
60+
private static DateTimeOffset? ReadDateTime(ref Utf8JsonReader reader, JsonSerializerOptions options)
61+
{
62+
// Detect ISO 8601-1:2019 extended year format (prefixed with '-' or '+') which cannot be
63+
// represented by DateTimeOffset. Clamp to the nearest representable value.
64+
if (reader.TokenType is JsonTokenType.String)
65+
{
66+
var span = reader.ValueSpan;
67+
if (span.Length > 0 && span[0] == (byte)'-')
68+
return DateTimeOffset.MinValue;
69+
if (span.Length > 0 && span[0] == (byte)'+')
70+
return DateTimeOffset.MaxValue;
71+
}
72+
73+
return reader.ReadNullableValueEx<DateTimeOffset>(options, typeof(DateTimeMarker));
74+
}
75+
}

0 commit comments

Comments
 (0)