diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/Username.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/Username.cs index 91ecae63213..6333625e868 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/Username.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/Username.cs @@ -79,16 +79,16 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov } internal sealed class UsernameConverter : - JsonConverter + JsonConverter { - public override Name? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override Username? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { reader.ValidateToken(JsonTokenType.String); return reader.GetString()!; } - public override Name ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, + public override Username ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { reader.ValidateToken(JsonTokenType.PropertyName); @@ -96,7 +96,7 @@ public override Name ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToCo return reader.GetString()!; } - public override void Write(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, Username value, JsonSerializerOptions options) { if (value?.Value is null) { @@ -106,7 +106,7 @@ public override void Write(Utf8JsonWriter writer, Name value, JsonSerializerOpti writer.WriteStringValue(value.Value); } - public override void WriteAsPropertyName(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) + public override void WriteAsPropertyName(Utf8JsonWriter writer, Username value, JsonSerializerOptions options) { if (value?.Value is null) { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs index 2307706f29b..10ecb87b245 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs @@ -19,9 +19,70 @@ public sealed partial class GeoBounds internal sealed class GeoBoundsConverter : JsonConverter { + // Coordinates. + + private static readonly JsonEncodedText PropBottom = JsonEncodedText.Encode("bottom"); + private static readonly JsonEncodedText PropLeft = JsonEncodedText.Encode("left"); + private static readonly JsonEncodedText PropRight = JsonEncodedText.Encode("right"); + private static readonly JsonEncodedText PropTop = JsonEncodedText.Encode("top"); + + // TopLeftBottomRight. + + private static readonly JsonEncodedText PropBottomRight = JsonEncodedText.Encode("bottom_right"); + private static readonly JsonEncodedText PropTopLeft = JsonEncodedText.Encode("top_left"); + + // TopRightBottomLeft. + + private static readonly JsonEncodedText PropBottomLeft = JsonEncodedText.Encode("bottom_left"); + private static readonly JsonEncodedText PropTopRight = JsonEncodedText.Encode("top_right"); + + // WKT. + + private static readonly JsonEncodedText PropWkt = JsonEncodedText.Encode("wkt"); + public override GeoBounds? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new InvalidOperationException(); + reader.ValidateToken(JsonTokenType.StartObject); + + var readerSnapshot = reader; + reader.Read(); + + GeoBounds.Kind? kind = null; + if (reader.TokenType is JsonTokenType.PropertyName) + { + if (reader.ValueTextEquals(PropBottom) || reader.ValueTextEquals(PropLeft) || + reader.ValueTextEquals(PropRight) || reader.ValueTextEquals(PropTop)) + { + kind = GeoBounds.Kind.Coordinates; + } + + if (reader.ValueTextEquals(PropBottomRight) || reader.ValueTextEquals(PropTopLeft)) + { + kind = GeoBounds.Kind.TopLeftBottomRight; + } + + if (reader.ValueTextEquals(PropBottomLeft) || reader.ValueTextEquals(PropTopRight)) + { + kind = GeoBounds.Kind.TopRightBottomLeft; + } + + if (reader.ValueTextEquals(PropWkt)) + { + kind = GeoBounds.Kind.Wkt; + } + } + + reader = readerSnapshot; + + return kind switch + { + GeoBounds.Kind.Coordinates => new(reader.ReadValue(options)), + GeoBounds.Kind.TopLeftBottomRight => new(reader.ReadValue(options)), + GeoBounds.Kind.TopRightBottomLeft => new(reader.ReadValue(options)), + GeoBounds.Kind.Wkt => new(reader.ReadValue(options)), + null => throw new JsonException($"Unrecognized '{typeof(GeoBounds)}' variant."), + _ => throw new InvalidOperationException("unreachable") + }; } public override void Write(Utf8JsonWriter writer, GeoBounds value, JsonSerializerOptions options) diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs index 2b32d158871..ab2829f04fa 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs @@ -21,9 +21,58 @@ public partial class GeoLocation internal sealed class GeoLocationConverter : JsonConverter { + // LatitudeLongitude. + + private static readonly JsonEncodedText PropLat = JsonEncodedText.Encode("lat"); + private static readonly JsonEncodedText PropLon = JsonEncodedText.Encode("lon"); + + // GeoHash. + + private static readonly JsonEncodedText PropGeoHash = JsonEncodedText.Encode("geohash"); + public override GeoLocation? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - throw new InvalidOperationException(); + if (reader.TokenType is JsonTokenType.String) + { + return new GeoLocation(reader.GetString()!); + } + + if (reader.TokenType is JsonTokenType.StartArray) + { + return new GeoLocation(reader.ReadCollectionValue(options, null)!); + } + + if (reader.TokenType is JsonTokenType.StartObject) + { + var readerSnapshot = reader; + reader.Read(); + + GeoLocation.Kind? kind = null; + if (reader.TokenType is JsonTokenType.PropertyName) + { + if (reader.ValueTextEquals(PropLat) || reader.ValueTextEquals(PropLon)) + { + kind = GeoLocation.Kind.LatitudeLongitude; + } + + if (reader.ValueTextEquals(PropGeoHash)) + { + kind = GeoLocation.Kind.GeoHash; + } + } + + reader = readerSnapshot; + + return kind switch + { + GeoLocation.Kind.LatitudeLongitude => new(reader.ReadValue(options)), + GeoLocation.Kind.GeoHash => new(reader.ReadValue(options)), + null => throw new JsonException($"Unrecognized '{typeof(GeoLocation)}' variant."), + _ => throw new InvalidOperationException("unreachable") + }; + } + + throw new JsonException($"Unrecognized '{typeof(GeoLocation)}' variant."); } public override void Write(Utf8JsonWriter writer, GeoLocation value, JsonSerializerOptions options)