diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Api/BulkRequest.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Api/BulkRequest.g.cs index 4270b68bc63..b1772c8d64e 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Api/BulkRequest.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Api/BulkRequest.g.cs @@ -124,35 +124,6 @@ public sealed partial class BulkRequestParameters : Elastic.Transport.RequestPar public Elastic.Clients.Elasticsearch.WaitForActiveShards? WaitForActiveShards { get => Q("wait_for_active_shards"); set => Q("wait_for_active_shards", value); } } -internal sealed partial class BulkRequestConverter : System.Text.Json.Serialization.JsonConverter -{ - public override Elastic.Clients.Elasticsearch.BulkRequest Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) - { - reader.ValidateToken(System.Text.Json.JsonTokenType.StartObject); - while (reader.Read() && reader.TokenType is System.Text.Json.JsonTokenType.PropertyName) - { - if (options.UnmappedMemberHandling is System.Text.Json.Serialization.JsonUnmappedMemberHandling.Skip) - { - reader.Skip(); - continue; - } - - throw new System.Text.Json.JsonException($"Unknown JSON property '{reader.GetString()}' for type '{typeToConvert.Name}'."); - } - - reader.ValidateToken(System.Text.Json.JsonTokenType.EndObject); - return new Elastic.Clients.Elasticsearch.BulkRequest(Elastic.Clients.Elasticsearch.Serialization.JsonConstructorSentinel.Instance) - { - }; - } - - public override void Write(System.Text.Json.Utf8JsonWriter writer, Elastic.Clients.Elasticsearch.BulkRequest value, System.Text.Json.JsonSerializerOptions options) - { - writer.WriteStartObject(); - writer.WriteEndObject(); - } -} - /// /// /// Bulk index or delete documents. @@ -352,7 +323,6 @@ public override void Write(System.Text.Json.Utf8JsonWriter writer, Elastic.Clien /// Refer to the linked documentation for step-by-step instructions using the index settings API. /// /// -[System.Text.Json.Serialization.JsonConverter(typeof(Elastic.Clients.Elasticsearch.BulkRequestConverter))] public partial class BulkRequest : Elastic.Clients.Elasticsearch.Requests.PlainRequest { public BulkRequest(Elastic.Clients.Elasticsearch.IndexName? index) : base(r => r.Optional("index", index)) @@ -1443,4 +1413,4 @@ public Elastic.Clients.Elasticsearch.BulkRequestDescriptor RequestCon Instance.RequestConfiguration = configurationSelector.Invoke(Instance.RequestConfiguration is null ? new Elastic.Transport.RequestConfigurationDescriptor() : new Elastic.Transport.RequestConfigurationDescriptor(Instance.RequestConfiguration)) ?? Instance.RequestConfiguration; return this; } -} \ No newline at end of file +} diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchRequest.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchRequest.g.cs index 806a161caaa..c153caf9631 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchRequest.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchRequest.g.cs @@ -123,19 +123,6 @@ public sealed partial class MultiSearchRequestParameters : Elastic.Transport.Req public bool? TypedKeys { get => Q("typed_keys"); set => Q("typed_keys", value); } } -internal sealed partial class MultiSearchRequestConverter : System.Text.Json.Serialization.JsonConverter -{ - public override Elastic.Clients.Elasticsearch.MultiSearchRequest Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) - { - return new Elastic.Clients.Elasticsearch.MultiSearchRequest(Elastic.Clients.Elasticsearch.Serialization.JsonConstructorSentinel.Instance) { Searches = reader.ReadValue>(options, static System.Collections.Generic.ICollection (ref System.Text.Json.Utf8JsonReader r, System.Text.Json.JsonSerializerOptions o) => r.ReadCollectionValue(o, null)!) }; - } - - public override void Write(System.Text.Json.Utf8JsonWriter writer, Elastic.Clients.Elasticsearch.MultiSearchRequest value, System.Text.Json.JsonSerializerOptions options) - { - writer.WriteValue(options, value.Searches, static (System.Text.Json.Utf8JsonWriter w, System.Text.Json.JsonSerializerOptions o, System.Collections.Generic.ICollection v) => w.WriteCollectionValue(o, v, null)); - } -} - /// /// /// Run multiple searches. @@ -159,7 +146,6 @@ public override void Write(System.Text.Json.Utf8JsonWriter writer, Elastic.Clien /// When sending requests to this endpoint the Content-Type header should be set to application/x-ndjson. /// /// -[System.Text.Json.Serialization.JsonConverter(typeof(Elastic.Clients.Elasticsearch.MultiSearchRequestConverter))] public partial class MultiSearchRequest : Elastic.Clients.Elasticsearch.Requests.PlainRequest { [System.Obsolete("The request contains additional required properties that must be initialized. Please use an alternative constructor to ensure all required values are properly set.")] @@ -876,4 +862,4 @@ public Elastic.Clients.Elasticsearch.MultiSearchRequestDescriptor Req Instance.RequestConfiguration = configurationSelector.Invoke(Instance.RequestConfiguration is null ? new Elastic.Transport.RequestConfigurationDescriptor() : new Elastic.Transport.RequestConfigurationDescriptor(Instance.RequestConfiguration)) ?? Instance.RequestConfiguration; return this; } -} \ No newline at end of file +} diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchTemplateRequest.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchTemplateRequest.g.cs index 38b93d0e03d..6c7b3192e79 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchTemplateRequest.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchTemplateRequest.g.cs @@ -62,19 +62,6 @@ public sealed partial class MultiSearchTemplateRequestParameters : Elastic.Trans public bool? TypedKeys { get => Q("typed_keys"); set => Q("typed_keys", value); } } -internal sealed partial class MultiSearchTemplateRequestConverter : System.Text.Json.Serialization.JsonConverter -{ - public override Elastic.Clients.Elasticsearch.MultiSearchTemplateRequest Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) - { - return new Elastic.Clients.Elasticsearch.MultiSearchTemplateRequest(Elastic.Clients.Elasticsearch.Serialization.JsonConstructorSentinel.Instance) { SearchTemplates = reader.ReadValue>(options, static System.Collections.Generic.ICollection (ref System.Text.Json.Utf8JsonReader r, System.Text.Json.JsonSerializerOptions o) => r.ReadCollectionValue(o, null)!) }; - } - - public override void Write(System.Text.Json.Utf8JsonWriter writer, Elastic.Clients.Elasticsearch.MultiSearchTemplateRequest value, System.Text.Json.JsonSerializerOptions options) - { - writer.WriteValue(options, value.SearchTemplates, static (System.Text.Json.Utf8JsonWriter w, System.Text.Json.JsonSerializerOptions o, System.Collections.Generic.ICollection v) => w.WriteCollectionValue(o, v, null)); - } -} - /// /// /// Run multiple templated searches. @@ -94,7 +81,6 @@ public override void Write(System.Text.Json.Utf8JsonWriter writer, Elastic.Clien /// $ curl -H "Content-Type: application/x-ndjson" -XGET localhost:9200/_msearch/template --data-binary "@requests"; echo /// /// -[System.Text.Json.Serialization.JsonConverter(typeof(Elastic.Clients.Elasticsearch.MultiSearchTemplateRequestConverter))] public partial class MultiSearchTemplateRequest : Elastic.Clients.Elasticsearch.Requests.PlainRequest { [System.Obsolete("The request contains additional required properties that must be initialized. Please use an alternative constructor to ensure all required values are properly set.")] @@ -540,4 +526,4 @@ public Elastic.Clients.Elasticsearch.MultiSearchTemplateRequestDescriptor public int TotalResponses => Responses.Count > 0 ? Responses.Count : 0; } -public partial class MultiSearchRequest : IStreamSerializable +[JsonConverter(typeof(JsonIncompatibleConverter))] +public partial class MultiSearchRequest : + IStreamSerializable { // Any request may contain aggregations so we force `typed_keys` in order to successfully // deserialize them. diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Api/MultiSearchTemplateRequest.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Api/MultiSearchTemplateRequest.cs index 9c9c83744d1..3cb90b9478c 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Api/MultiSearchTemplateRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Api/MultiSearchTemplateRequest.cs @@ -20,7 +20,9 @@ public partial class MultiSearchTemplateResponse public int TotalResponses => Responses.Count > 0 ? Responses.Count : 0; } -public partial class MultiSearchTemplateRequest : IStreamSerializable +[JsonConverter(typeof(JsonIncompatibleConverter))] +public partial class MultiSearchTemplateRequest : + IStreamSerializable { internal override void BeforeRequest() => TypedKeys ??= true; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Api/ResponseItem.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Api/ResponseItem.cs index 628116b44c1..efd8f3210b1 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Api/ResponseItem.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Api/ResponseItem.cs @@ -7,7 +7,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -[JsonConverter(typeof(BulkResponseItemConverter))] +[JsonConverter(typeof(Json.BulkResponseItemConverter))] public abstract partial class ResponseItem { public abstract string Operation { get; } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Api/SearchRequest.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Api/SearchRequest.cs index 56383386fa1..3f82a968c2f 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Api/SearchRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Api/SearchRequest.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Text.Json; using System.Text.Json.Serialization; using Elastic.Clients.Elasticsearch.Requests; @@ -33,12 +32,12 @@ protected override (string ResolvedUrl, string UrlTemplate, Dictionary : SearchRequest { static SearchRequest() { - DynamicallyAccessed.PublicConstructors(typeof(SearchRequestOfTConverter)); + DynamicallyAccessed.PublicConstructors(typeof(Json.SearchRequestOfTConverter)); } public SearchRequest(Indices? indices) : base(indices) @@ -61,29 +60,3 @@ public SearchRequestDescriptor Pit(string id, Action - typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(SearchRequest<>); - - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - var args = typeToConvert.GetGenericArguments(); - -#pragma warning disable IL3050 - return (JsonConverter)Activator.CreateInstance(typeof(SearchRequestOfTConverter<>).MakeGenericType(args[0])); -#pragma warning restore IL3050 - } -} - -internal sealed class SearchRequestOfTConverter : - JsonConverter> -{ - public override SearchRequest? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => - throw new NotSupportedException(); - - public override void Write(Utf8JsonWriter writer, SearchRequest value, JsonSerializerOptions options) => - writer.WriteValue(options, (SearchRequest)value); -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Api/SearchRequestConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Api/SearchRequestConverter.cs new file mode 100644 index 00000000000..957f7b593ed --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Api/SearchRequestConverter.cs @@ -0,0 +1,37 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class SearchRequestOfTConverterFactory : + JsonConverterFactory +{ + public override bool CanConvert(Type typeToConvert) => + typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(SearchRequest<>); + + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + var args = typeToConvert.GetGenericArguments(); + +#pragma warning disable IL3050 + return (JsonConverter)Activator.CreateInstance(typeof(SearchRequestOfTConverter<>).MakeGenericType(args[0])); +#pragma warning restore IL3050 + } +} + +public sealed class SearchRequestOfTConverter : + JsonConverter> +{ + public override SearchRequest? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + throw new NotSupportedException(); + + public override void Write(Utf8JsonWriter writer, SearchRequest value, JsonSerializerOptions options) => + writer.WriteValue(options, (SearchRequest)value); +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMath.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMath.cs index 3ba67fee432..f7b21cfa916 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMath.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMath.cs @@ -6,13 +6,12 @@ using System.Collections.Generic; using System.Globalization; using System.Text; -using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(DateMathConverter))] +[JsonConverter(typeof(Json.DateMathConverter))] public abstract class DateMath { private static readonly Regex DateMathRegex = @@ -174,26 +173,3 @@ private static void AppendTwoDigitNumber(StringBuilder result, int val) result.Append((char)('0' + (val % 10))); } } - -internal sealed class DateMathConverter : JsonConverter -{ - public override DateMath? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.String) - return null; - - // TODO: Performance - Review potential to avoid allocation on DateTime path and use Span - - var value = reader.GetString(); - - if (!value.Contains("|") && DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime)) - return DateMath.Anchored(dateTime); - - return DateMath.Anchored(value); - } - - public override void Write(Utf8JsonWriter writer, DateMath value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.ToString()); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathConverter.cs new file mode 100644 index 00000000000..2d80e75495b --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathConverter.cs @@ -0,0 +1,33 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Globalization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DateMathConverter : JsonConverter +{ + public override DateMath? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) + return null; + + // TODO: Performance - Review potential to avoid allocation on DateTime path and use Span + + var value = reader.GetString(); + + if (!value.Contains("|") && DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime)) + return DateMath.Anchored(dateTime); + + return DateMath.Anchored(value); + } + + public override void Write(Utf8JsonWriter writer, DateMath value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathExpression.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathExpression.cs index bac070f3404..dbea591c497 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathExpression.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathExpression.cs @@ -3,18 +3,20 @@ // See the LICENSE file in the project root for more information. using System; -using System.Globalization; -using System.Text.Json; using System.Text.Json.Serialization; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(DateMathExpressionConverter))] +[JsonConverter(typeof(Json.DateMathExpressionConverter))] public class DateMathExpression : DateMath { - public DateMathExpression(string anchor) : base(anchor) { } + public DateMathExpression(string anchor) : base(anchor) + { + } - public DateMathExpression(DateTime anchor) : base(anchor) { } + public DateMathExpression(DateTime anchor) : base(anchor) + { + } public DateMathExpression(Union anchor, DateMathTime range, DateMathOperation operation) : base(anchor, range, operation) { } @@ -43,33 +45,3 @@ public DateMath RoundTo(DateMathTimeUnit round) return this; } } - -internal sealed class DateMathExpressionConverter : JsonConverter -{ - public override DateMathExpression? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.String) - return null; - - // TODO: Performance - Review potential to avoid allocation on DateTime path and use Span - - var value = reader.GetString(); - reader.Read(); - - if (!value.Contains("|") && DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime)) - return DateMath.Anchored(dateTime); - - return new DateMathExpression(value); - } - - public override void Write(Utf8JsonWriter writer, DateMathExpression value, JsonSerializerOptions options) - { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - writer.WriteStringValue(value.ToString()); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathExpressionConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathExpressionConverter.cs new file mode 100644 index 00000000000..7f1ff77cd7b --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathExpressionConverter.cs @@ -0,0 +1,40 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Globalization; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DateMathExpressionConverter : JsonConverter +{ + public override DateMathExpression? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) + return null; + + // TODO: Performance - Review potential to avoid allocation on DateTime path and use Span + + var value = reader.GetString(); + reader.Read(); + + if (!value.Contains("|") && DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime)) + return DateMath.Anchored(dateTime); + + return new DateMathExpression(value); + } + + public override void Write(Utf8JsonWriter writer, DateMathExpression value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStringValue(value.ToString()); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathOperation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathOperation.cs index 1498e7538ba..f47649876f9 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathOperation.cs @@ -4,12 +4,11 @@ using System; using System.Runtime.Serialization; -using System.Text.Json; using System.Text.Json.Serialization; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(DateMathOperationConverter))] +[JsonConverter(typeof(Json.DateMathOperationConverter))] public enum DateMathOperation { [EnumMember(Value = "+")] @@ -19,39 +18,6 @@ public enum DateMathOperation Subtract } -internal sealed class DateMathOperationConverter : JsonConverter -{ - public override DateMathOperation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var enumString = reader.GetString(); - switch (enumString) - { - case "+": - return DateMathOperation.Add; - case "-": - return DateMathOperation.Subtract; - } - - ThrowHelper.ThrowJsonException(); - return default; - } - - public override void Write(Utf8JsonWriter writer, DateMathOperation value, JsonSerializerOptions options) - { - switch (value) - { - case DateMathOperation.Add: - writer.WriteStringValue("+"); - return; - case DateMathOperation.Subtract: - writer.WriteStringValue("-"); - return; - } - - writer.WriteNullValue(); - } -} - public static class DateMathOperationExtensions { public static string GetStringValue(this DateMathOperation value) @@ -60,8 +26,10 @@ public static string GetStringValue(this DateMathOperation value) { case DateMathOperation.Add: return "+"; + case DateMathOperation.Subtract: return "-"; + default: throw new ArgumentOutOfRangeException(nameof(value), value, null); } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathOperationConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathOperationConverter.cs new file mode 100644 index 00000000000..f2420ecc36e --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathOperationConverter.cs @@ -0,0 +1,44 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DateMathOperationConverter : JsonConverter +{ + public override DateMathOperation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var enumString = reader.GetString(); + switch (enumString) + { + case "+": + return DateMathOperation.Add; + + case "-": + return DateMathOperation.Subtract; + } + + ThrowHelper.ThrowJsonException(); + return default; + } + + public override void Write(Utf8JsonWriter writer, DateMathOperation value, JsonSerializerOptions options) + { + switch (value) + { + case DateMathOperation.Add: + writer.WriteStringValue("+"); + return; + + case DateMathOperation.Subtract: + writer.WriteStringValue("-"); + return; + } + + writer.WriteNullValue(); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTime.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTime.cs index 2ad53509839..aa50acff8f3 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTime.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTime.cs @@ -4,7 +4,6 @@ using System; using System.Globalization; -using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; @@ -13,7 +12,7 @@ namespace Elastic.Clients.Elasticsearch; /// /// A time representation for use within expressions. /// -[JsonConverter(typeof(DateMathTimeConverter))] +[JsonConverter(typeof(Json.DateMathTimeConverter))] public class DateMathTime : IComparable, IEquatable { private const double MillisecondsInADay = MillisecondsInAnHour * 24; @@ -64,11 +63,14 @@ public DateMathTime(int factor, DateMathTimeUnit interval) => /// public DateMathTime(string timeUnit, MidpointRounding rounding = MidpointRounding.AwayFromZero) { - if (timeUnit == null) throw new ArgumentNullException(nameof(timeUnit)); - if (timeUnit.Length == 0) throw new ArgumentException("Expression string is empty", nameof(timeUnit)); + if (timeUnit == null) + throw new ArgumentNullException(nameof(timeUnit)); + if (timeUnit.Length == 0) + throw new ArgumentException("Expression string is empty", nameof(timeUnit)); var match = ExpressionRegex.Match(timeUnit); - if (!match.Success) throw new ArgumentException($"Expression '{timeUnit}' string is invalid", nameof(timeUnit)); + if (!match.Success) + throw new ArgumentException($"Expression '{timeUnit}' string is invalid", nameof(timeUnit)); var factor = match.Groups["factor"].Value; if (!double.TryParse(factor, NumberStyles.Any, CultureInfo.InvariantCulture, out var fraction)) @@ -97,17 +99,22 @@ public DateMathTime(string timeUnit, MidpointRounding rounding = MidpointRoundin public int CompareTo(DateMathTime other) { - if (other == null) return 1; - if (Math.Abs(_approximateSeconds - other._approximateSeconds) < double.Epsilon) return 0; - if (_approximateSeconds < other._approximateSeconds) return -1; + if (other == null) + return 1; + if (Math.Abs(_approximateSeconds - other._approximateSeconds) < double.Epsilon) + return 0; + if (_approximateSeconds < other._approximateSeconds) + return -1; return 1; } public bool Equals(DateMathTime other) { - if (other is null) return false; - if (ReferenceEquals(this, other)) return true; + if (other is null) + return false; + if (ReferenceEquals(this, other)) + return true; return Math.Abs(_approximateSeconds - other._approximateSeconds) < double.Epsilon; } @@ -133,24 +140,31 @@ private void SetWholeFactorIntervalAndSeconds(double factor, DateMathTimeUnit in case DateMathTimeUnit.Second: _approximateSeconds = whole; break; + case DateMathTimeUnit.Minute: _approximateSeconds = whole * (MillisecondsInAMinute / MillisecondsInASecond); break; + case DateMathTimeUnit.Hour: _approximateSeconds = whole * (MillisecondsInAnHour / MillisecondsInASecond); break; + case DateMathTimeUnit.Day: _approximateSeconds = whole * (MillisecondsInADay / MillisecondsInASecond); break; + case DateMathTimeUnit.Week: _approximateSeconds = whole * (MillisecondsInAWeek / MillisecondsInASecond); break; + case DateMathTimeUnit.Month: _approximateSeconds = whole * (MillisecondsInAMonthApproximate / MillisecondsInASecond); break; + case DateMathTimeUnit.Year: _approximateSeconds = whole * (MillisecondsInAYearApproximate / MillisecondsInASecond); break; + default: throw new ArgumentOutOfRangeException(nameof(interval), interval, null); } @@ -162,18 +176,23 @@ private void SetWholeFactorIntervalAndSeconds(double factor, DateMathTimeUnit in case DateMathTimeUnit.Second: milliseconds = factor * MillisecondsInASecond; break; + case DateMathTimeUnit.Minute: milliseconds = factor * MillisecondsInAMinute; break; + case DateMathTimeUnit.Hour: milliseconds = factor * MillisecondsInAnHour; break; + case DateMathTimeUnit.Day: milliseconds = factor * MillisecondsInADay; break; + case DateMathTimeUnit.Week: milliseconds = factor * MillisecondsInAWeek; break; + case DateMathTimeUnit.Month: if (TryGetIntegerGreaterThanZero(fraction, out whole)) { @@ -185,6 +204,7 @@ private void SetWholeFactorIntervalAndSeconds(double factor, DateMathTimeUnit in milliseconds = factor * MillisecondsInAMonthApproximate; break; + case DateMathTimeUnit.Year: if (TryGetIntegerGreaterThanZero(fraction, out whole)) { @@ -204,6 +224,7 @@ private void SetWholeFactorIntervalAndSeconds(double factor, DateMathTimeUnit in } milliseconds = factor * MillisecondsInAYearApproximate; break; + default: throw new ArgumentOutOfRangeException(nameof(interval), interval, null); } @@ -307,9 +328,12 @@ private static bool TryGetIntegerGreaterThanZero(double d, out int value) public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + if (obj.GetType() != GetType()) + return false; return Equals((DateMathTime)obj); } @@ -317,24 +341,3 @@ public override bool Equals(object obj) // ReSharper disable once NonReadonlyMemberInGetHashCode public override int GetHashCode() => _approximateSeconds.GetHashCode(); } - -internal sealed class DateMathTimeConverter : JsonConverter -{ - public override DateMathTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var value = reader.GetString(); - reader.Read(); - return value; - } - - public override void Write(Utf8JsonWriter writer, DateMathTime value, JsonSerializerOptions options) - { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - writer.WriteStringValue(value.ToString()); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeConverter.cs new file mode 100644 index 00000000000..ef3616e1c1a --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeConverter.cs @@ -0,0 +1,30 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DateMathTimeConverter : JsonConverter +{ + public override DateMathTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var value = reader.GetString(); + reader.Read(); + return value; + } + + public override void Write(Utf8JsonWriter writer, DateMathTime value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStringValue(value.ToString()); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeUnit.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeUnit.cs index 89a2facf99e..d399a3b655e 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeUnit.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeUnit.cs @@ -4,12 +4,11 @@ using System; using System.Runtime.Serialization; -using System.Text.Json; using System.Text.Json.Serialization; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(DateMathTimeUnitConverter))] +[JsonConverter(typeof(Json.DateMathTimeUnitConverter))] public enum DateMathTimeUnit { [EnumMember(Value = "s")] @@ -34,64 +33,6 @@ public enum DateMathTimeUnit Year } -internal sealed class DateMathTimeUnitConverter : JsonConverter -{ - public override DateMathTimeUnit Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var enumString = reader.GetString(); - switch (enumString) - { - case "h": - return DateMathTimeUnit.Hour; - case "m": - return DateMathTimeUnit.Minute; - case "s": - return DateMathTimeUnit.Second; - case "d": - return DateMathTimeUnit.Day; - case "w": - return DateMathTimeUnit.Week; - case "M": - return DateMathTimeUnit.Month; - case "y": - return DateMathTimeUnit.Year; - } - - ThrowHelper.ThrowJsonException(); - return default; - } - - public override void Write(Utf8JsonWriter writer, DateMathTimeUnit value, JsonSerializerOptions options) - { - switch (value) - { - case DateMathTimeUnit.Hour: - writer.WriteStringValue("h"); - return; - case DateMathTimeUnit.Minute: - writer.WriteStringValue("m"); - return; - case DateMathTimeUnit.Second: - writer.WriteStringValue("s"); - return; - case DateMathTimeUnit.Day: - writer.WriteStringValue("d"); - return; - case DateMathTimeUnit.Week: - writer.WriteStringValue("w"); - return; - case DateMathTimeUnit.Month: - writer.WriteStringValue("M"); - return; - case DateMathTimeUnit.Year: - writer.WriteStringValue("y"); - return; - } - - writer.WriteNullValue(); - } -} - public static class DateMathTimeUnitExtensions { public static string GetStringValue(this DateMathTimeUnit value) => diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeUnitConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeUnitConverter.cs new file mode 100644 index 00000000000..2a1c7300325 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DateMath/DateMathTimeUnitConverter.cs @@ -0,0 +1,79 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DateMathTimeUnitConverter : JsonConverter +{ + public override DateMathTimeUnit Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var enumString = reader.GetString(); + switch (enumString) + { + case "h": + return DateMathTimeUnit.Hour; + + case "m": + return DateMathTimeUnit.Minute; + + case "s": + return DateMathTimeUnit.Second; + + case "d": + return DateMathTimeUnit.Day; + + case "w": + return DateMathTimeUnit.Week; + + case "M": + return DateMathTimeUnit.Month; + + case "y": + return DateMathTimeUnit.Year; + } + + ThrowHelper.ThrowJsonException(); + return default; + } + + public override void Write(Utf8JsonWriter writer, DateMathTimeUnit value, JsonSerializerOptions options) + { + switch (value) + { + case DateMathTimeUnit.Hour: + writer.WriteStringValue("h"); + return; + + case DateMathTimeUnit.Minute: + writer.WriteStringValue("m"); + return; + + case DateMathTimeUnit.Second: + writer.WriteStringValue("s"); + return; + + case DateMathTimeUnit.Day: + writer.WriteStringValue("d"); + return; + + case DateMathTimeUnit.Week: + writer.WriteStringValue("w"); + return; + + case DateMathTimeUnit.Month: + writer.WriteStringValue("M"); + return; + + case DateMathTimeUnit.Year: + writer.WriteStringValue("y"); + return; + } + + writer.WriteNullValue(); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/Duration.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/Duration.cs index 4cb84be9e0e..52078befeb9 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/Duration.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/Duration.cs @@ -3,12 +3,11 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; + using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; @@ -16,7 +15,7 @@ namespace Elastic.Clients.Elasticsearch; /// /// Represents a duration value. /// -[JsonConverter(typeof(DurationConverter))] +[JsonConverter(typeof(Json.DurationConverter))] public sealed class Duration : IComparable, IEquatable, @@ -125,24 +124,31 @@ private void ParseExpression(string timeUnit) case "m": Interval = TimeUnit.Minutes; break; + case "s": Interval = TimeUnit.Seconds; break; + case "ms": Interval = TimeUnit.Milliseconds; break; + case "ns": Interval = TimeUnit.Nanoseconds; break; + case "h": Interval = TimeUnit.Hours; break; + case "d": Interval = TimeUnit.Days; break; + case "micros": Interval = TimeUnit.Microseconds; break; + case "nanos": Interval = TimeUnit.Nanoseconds; break; @@ -229,10 +235,12 @@ public TimeSpan ToTimeSpan() if (!Factor.HasValue) throw new InvalidOperationException("Time is in microseconds but factor has no value, this is a bug please report!"); return TimeSpan.FromTicks((long)(Factor.Value / MicrosecondsInATick)); + case TimeUnit.Nanoseconds: if (!Factor.HasValue) throw new InvalidOperationException("Time is in nanoseconds but factor has no value, this is a bug please report!"); return TimeSpan.FromTicks((long)(Factor.Value / NanosecondsInATick)); + default: if (!Milliseconds.HasValue) throw new InvalidOperationException("Milliseconds is null so we have nothing to create a TimeSpan from, this is a bug please report!"); @@ -277,7 +285,6 @@ public bool Equals(Duration other) if (StaticTimeValue.HasValue && other.StaticTimeValue.HasValue) return StaticTimeValue == other.StaticTimeValue; - if (Milliseconds == null && other.Milliseconds == null) return true; if (Milliseconds == null || other.Milliseconds == null) @@ -373,18 +380,25 @@ private static double GetExactMilliseconds(double factor, TimeUnit interval) { case TimeUnit.Days: return factor * MillisecondsInADay; + case TimeUnit.Hours: return factor * MillisecondsInAnHour; + case TimeUnit.Minutes: return factor * MillisecondsInAMinute; + case TimeUnit.Seconds: return factor * MillisecondsInASecond; + case TimeUnit.Milliseconds: return factor; + case TimeUnit.Microseconds: return factor * MillisecondsInAMicrosecond; + case TimeUnit.Nanoseconds: return factor * MillisecondsInANanosecond; + default: throw new ArgumentOutOfRangeException(nameof(interval), interval, null); } @@ -428,38 +442,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class DurationConverter : JsonConverter -{ - public override Duration? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var token = reader.TokenType; - - switch (token) - { - case JsonTokenType.String: - return new Duration(reader.GetString()); - case JsonTokenType.Number: - var milliseconds = reader.GetInt64(); - if (milliseconds == -1) - return Duration.MinusOne; - if (milliseconds == 0) - return Duration.Zero; - return new Duration(milliseconds); - default: - return null; - } - } - - public override void Write(Utf8JsonWriter writer, Duration value, JsonSerializerOptions options) - { - if (value == Duration.MinusOne) - writer.WriteNumberValue(-1); - else if (value == Duration.Zero) - writer.WriteNumberValue(0); - else if (value.Factor.HasValue && value.Interval.HasValue) - writer.WriteStringValue(value.ToString()); - else if (value.Milliseconds != null) - writer.WriteNumberValue((long)value.Milliseconds); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DurationConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DurationConverter.cs new file mode 100644 index 00000000000..943182b84e3 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/DurationConverter.cs @@ -0,0 +1,46 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DurationConverter : JsonConverter +{ + public override Duration? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var token = reader.TokenType; + + switch (token) + { + case JsonTokenType.String: + return new Duration(reader.GetString()); + + case JsonTokenType.Number: + var milliseconds = reader.GetInt64(); + if (milliseconds == -1) + return Duration.MinusOne; + if (milliseconds == 0) + return Duration.Zero; + return new Duration(milliseconds); + + default: + return null; + } + } + + public override void Write(Utf8JsonWriter writer, Duration value, JsonSerializerOptions options) + { + if (value == Duration.MinusOne) + writer.WriteNumberValue(-1); + else if (value == Duration.Zero) + writer.WriteNumberValue(0); + else if (value.Factor.HasValue && value.Interval.HasValue) + writer.WriteStringValue(value.ToString()); + else if (value.Milliseconds != null) + writer.WriteNumberValue((long)value.Milliseconds); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValue.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValue.cs index ae0c5110f50..e6c45d5aa83 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValue.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValue.cs @@ -3,12 +3,10 @@ // See the LICENSE file in the project root for more information. using System.Text.Json.Serialization; -using System.Text.Json; using System; using System.Diagnostics.CodeAnalysis; using System.Collections.Generic; using System.Globalization; -using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch; @@ -16,7 +14,7 @@ namespace Elastic.Clients.Elasticsearch; /// Represents a value for a field which depends on the field mapping and is only known at runtime, /// therefore cannot be specifically typed. /// -[JsonConverter(typeof(FieldValueConverter))] +[JsonConverter(typeof(Json.FieldValueConverter))] public readonly struct FieldValue : IEquatable { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValueConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValueConverter.cs index 58e04fb7f72..943a958cc75 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValueConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Fields/FieldValueConverter.cs @@ -8,9 +8,9 @@ using System.Text.Json; using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Json; -internal sealed class FieldValueConverter : +public sealed class FieldValueConverter : JsonConverter { public override FieldValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/Field.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/Field.cs index cb73354578e..2dd003563b3 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/Field.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/Field.cs @@ -12,14 +12,9 @@ using Elastic.Transport; -#if ELASTICSEARCH_SERVERLESS -namespace Elastic.Clients.Elasticsearch.Serverless; -#else - namespace Elastic.Clients.Elasticsearch; -#endif -[JsonConverter(typeof(FieldConverter))] +[JsonConverter(typeof(Json.FieldConverter))] [DebuggerDisplay($"{{{nameof(DebuggerDisplay)},nq}}")] public sealed class Field : IEquatable, diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/FieldConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/FieldConverter.cs index b12a2e16a5c..058d8349f0f 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/FieldConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/FieldConverter.cs @@ -8,9 +8,9 @@ using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Json; -internal sealed class FieldConverter : +public sealed class FieldConverter : JsonConverter { public override Field Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/Fields.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/Fields.cs index 7fd300c5149..6befea25ae2 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/Fields.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/Fields.cs @@ -12,12 +12,11 @@ using System.Reflection; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(FieldsConverter))] +[JsonConverter(typeof(Json.FieldsConverter))] [DebuggerDisplay($"{{{nameof(DebuggerDisplay)},nq}}")] public sealed class Fields : IEquatable, diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/FieldsConverter.Specialized.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/FieldsConverter.Specialized.cs new file mode 100644 index 00000000000..8dc15041d4f --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/FieldsConverter.Specialized.cs @@ -0,0 +1,54 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class SingleOrManyFieldsMarker; + +internal sealed class SingleOrManyFieldsMarkerConverter : + JsonConverter, + IMarkerTypeConverter +{ + public JsonConverter WrappedConverter { get; } + + public SingleOrManyFieldsMarkerConverter() + { + WrappedConverter = new SingleOrManyFieldsConverter(); + } + + public override SingleOrManyFieldsMarker Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new InvalidOperationException(); + } + + public override void Write(Utf8JsonWriter writer, SingleOrManyFieldsMarker value, JsonSerializerOptions options) + { + throw new InvalidOperationException(); + } +} + +internal sealed class SingleOrManyFieldsConverter : + JsonConverter +{ + public override Fields Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var fields = reader.ReadSingleOrManyCollectionValue(options, null)!; + + return new Fields(fields); + } + + public override void Write(Utf8JsonWriter writer, Fields value, JsonSerializerOptions options) + { + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + writer.WriteSingleOrManyCollectionValue(options, value.ListOfFields, null); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/FieldsConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/FieldsConverter.cs index cd5af1af706..a44ee40048d 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/FieldsConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/FieldsConverter.cs @@ -3,13 +3,14 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; -internal sealed class FieldsConverter : +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class FieldsConverter : JsonConverter { public override Fields Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) @@ -29,48 +30,3 @@ public override void Write(Utf8JsonWriter writer, Fields value, JsonSerializerOp writer.WriteCollectionValue(options, value.ListOfFields, null); } } - -internal sealed class SingleOrManyFieldsMarker; - -internal sealed class SingleOrManyFieldsMarkerConverter : - JsonConverter, - IMarkerTypeConverter -{ - public JsonConverter WrappedConverter { get; } - - public SingleOrManyFieldsMarkerConverter() - { - WrappedConverter = new SingleOrManyFieldsConverter(); - } - - public override SingleOrManyFieldsMarker Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - throw new InvalidOperationException(); - } - - public override void Write(Utf8JsonWriter writer, SingleOrManyFieldsMarker value, JsonSerializerOptions options) - { - throw new InvalidOperationException(); - } -} - -internal sealed class SingleOrManyFieldsConverter : - JsonConverter -{ - public override Fields Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var fields = reader.ReadSingleOrManyCollectionValue(options, null)!; - - return new Fields(fields); - } - - public override void Write(Utf8JsonWriter writer, Fields value, JsonSerializerOptions options) - { - if (value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - writer.WriteSingleOrManyCollectionValue(options, value.ListOfFields, null); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Ids.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Ids.cs index b642adb7958..25a39c67f50 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Ids.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Ids.cs @@ -14,7 +14,7 @@ namespace Elastic.Clients.Elasticsearch; [DebuggerDisplay("{DebugDisplay,nq}")] -[JsonConverter(typeof(IdsConverter))] +[JsonConverter(typeof(Json.IdsConverter))] public class Ids : IUrlParameter, IEquatable diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdsConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdsConverter.cs index 3d16fd1188b..08ce6aeda64 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdsConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdsConverter.cs @@ -8,9 +8,9 @@ using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Json; -internal sealed class IdsConverter : JsonConverter +public sealed class IdsConverter : JsonConverter { public override Ids? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexName.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexName.cs index f84684a99c8..4c968b7b94f 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexName.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexName.cs @@ -14,7 +14,7 @@ namespace Elastic.Clients.Elasticsearch; /// /// Represents the name of an index, which may be inferred from a . /// -[JsonConverter(typeof(IndexNameConverter))] +[JsonConverter(typeof(Json.IndexNameConverter))] [DebuggerDisplay("{DebugDisplay,nq}")] public class IndexName : IEquatable, diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexNameConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexNameConverter.cs index 675f04d48a5..ec6ad44a350 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexNameConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexNameConverter.cs @@ -8,12 +8,12 @@ using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Json; /// /// Converts an to and from its JSON representation. /// -internal class IndexNameConverter : JsonConverter +public sealed class IndexNameConverter : JsonConverter { private IElasticsearchClientSettings _settings; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/Indices.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/Indices.cs index 6c86df1180a..dfcb8426127 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/Indices.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/Indices.cs @@ -8,16 +8,14 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; [DebuggerDisplay("{DebugDisplay,nq}")] -[JsonConverter(typeof(IndicesJsonConverter))] +[JsonConverter(typeof(Json.IndicesJsonConverter))] public sealed class Indices : IUrlParameter, IEnumerable, @@ -240,19 +238,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class IndicesJsonConverter : - JsonConverter -{ - public override Indices Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var indices = reader.ReadSingleOrManyCollectionValue(options, null)!; - - return new Indices(indices); - } - - public override void Write(Utf8JsonWriter writer, Indices value, JsonSerializerOptions options) - { - writer.WriteSingleOrManyCollectionValue(options, value.IndexNames, null); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/IndicesConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/IndicesConverter.cs new file mode 100644 index 00000000000..ccb0385a262 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/IndicesConverter.cs @@ -0,0 +1,27 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class IndicesJsonConverter : + JsonConverter +{ + public override Indices Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var indices = reader.ReadSingleOrManyCollectionValue(options, null)!; + + return new Indices(indices); + } + + public override void Write(Utf8JsonWriter writer, Indices value, JsonSerializerOptions options) + { + writer.WriteSingleOrManyCollectionValue(options, value.IndexNames, null); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinField.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinField.cs index d3b791c999a..1424f296eb5 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinField.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinField.cs @@ -7,7 +7,7 @@ namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(JoinFieldConverter))] +[JsonConverter(typeof(Json.JoinFieldConverter))] public class JoinField { internal Child ChildOption { get; } @@ -51,8 +51,10 @@ public T Match(Func first, Func second) { case 0: return first(ParentOption); + case 1: return second(ChildOption); + default: throw new Exception($"Unrecognized tag value: {Tag}"); } @@ -65,9 +67,11 @@ public void Match(Action first, Action second) case 0: first(ParentOption); break; + case 1: second(ChildOption); break; + default: throw new Exception($"Unrecognized tag value: {Tag}"); } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldConverter.cs index 78367211175..10b10c8de8c 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldConverter.cs @@ -8,9 +8,9 @@ using Elastic.Transport; using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Json; -internal sealed class JoinFieldConverter : JsonConverter +public sealed class JoinFieldConverter : JsonConverter { private static readonly JsonEncodedText PropName = JsonEncodedText.Encode("name"); private static readonly JsonEncodedText PropParent = JsonEncodedText.Encode("parent"); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/PropertyName/PropertyName.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/PropertyName/PropertyName.cs index 40b1b161868..3a2f0645362 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/PropertyName/PropertyName.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/PropertyName/PropertyName.cs @@ -6,16 +6,14 @@ using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; [DebuggerDisplay("{" + nameof(DebugDisplay) + ",nq}")] -[JsonConverter(typeof(PropertyNameConverter))] +[JsonConverter(typeof(Json.PropertyNameConverter))] public sealed class PropertyName : IEquatable, IUrlParameter { private readonly object _comparisonValue; @@ -118,36 +116,3 @@ public bool EqualsMarker(PropertyName other) => _type != null public static bool operator !=(PropertyName left, PropertyName right) => !Equals(left, right); } - -internal sealed class PropertyNameConverter : - JsonConverter -{ - public override PropertyName Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.String); - - return new PropertyName(reader.GetString()!); - } - - public override void Write(Utf8JsonWriter writer, PropertyName value, JsonSerializerOptions options) - { - var settings = options.GetContext(); - var fieldName = settings.Inferrer.PropertyName(value); - - writer.WriteStringValue(fieldName); - } - - public override PropertyName ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.PropertyName); - - return new PropertyName(reader.GetString()!); - } - - public override void WriteAsPropertyName(Utf8JsonWriter writer, PropertyName value, JsonSerializerOptions options) - { - var settings = options.GetContext(); - - writer.WritePropertyName(settings.Inferrer.PropertyName(value)); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/PropertyName/PropertyNameConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/PropertyName/PropertyNameConverter.cs new file mode 100644 index 00000000000..66f43235928 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/PropertyName/PropertyNameConverter.cs @@ -0,0 +1,44 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class PropertyNameConverter : + JsonConverter +{ + public override PropertyName Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.String); + + return new PropertyName(reader.GetString()!); + } + + public override void Write(Utf8JsonWriter writer, PropertyName value, JsonSerializerOptions options) + { + var settings = options.GetContext(); + var fieldName = settings.Inferrer.PropertyName(value); + + writer.WriteStringValue(fieldName); + } + + public override PropertyName ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.PropertyName); + + return new PropertyName(reader.GetString()!); + } + + public override void WriteAsPropertyName(Utf8JsonWriter writer, PropertyName value, JsonSerializerOptions options) + { + var settings = options.GetContext(); + + writer.WritePropertyName(settings.Inferrer.PropertyName(value)); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/RelationName/RelationName.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/RelationName/RelationName.cs index 7808bed02b4..cd4106f44bb 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/RelationName/RelationName.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/RelationName/RelationName.cs @@ -5,12 +5,10 @@ using System; using Elastic.Transport; using System.Text.Json.Serialization; -using System.Text.Json; -using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(RelationNameConverter))] +[JsonConverter(typeof(Json.RelationNameConverter))] public sealed class RelationName : IEquatable, IUrlParameter { private RelationName(string type) => Name = type; @@ -78,43 +76,3 @@ public bool EqualsMarker(RelationName other) public override string ToString() => DebugDisplay; } - -internal sealed class RelationNameConverter : JsonConverter -{ - private IElasticsearchClientSettings? _settings; - - public override RelationName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.String) - { - RelationName relationName = reader.GetString(); - return relationName; - } - - return null; - } - - public override void Write(Utf8JsonWriter writer, RelationName value, JsonSerializerOptions options) - { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - InitializeSettings(options); - var relationName = _settings.Inferrer.RelationName(value); - writer.WriteStringValue(relationName); - } - - private void InitializeSettings(JsonSerializerOptions options) - { - if (_settings is null) - { - if (!options.TryGetClientSettings(out var settings)) - ThrowHelper.ThrowJsonExceptionForMissingSettings(); - - _settings = settings; - } - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/RelationName/RelationNameConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/RelationName/RelationNameConverter.cs new file mode 100644 index 00000000000..8c89f8e20e1 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/RelationName/RelationNameConverter.cs @@ -0,0 +1,50 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json.Serialization; +using System.Text.Json; +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class RelationNameConverter : JsonConverter +{ + private IElasticsearchClientSettings? _settings; + + public override RelationName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + RelationName relationName = reader.GetString(); + return relationName; + } + + return null; + } + + public override void Write(Utf8JsonWriter writer, RelationName value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + InitializeSettings(options); + var relationName = _settings.Inferrer.RelationName(value); + writer.WriteStringValue(relationName); + } + + private void InitializeSettings(JsonSerializerOptions options) + { + if (_settings is null) + { + if (!options.TryGetClientSettings(out var settings)) + ThrowHelper.ThrowJsonExceptionForMissingSettings(); + + _settings = settings; + } + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/LazyJson.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/LazyJson.cs index ad23b24088a..6554e86f3a7 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/LazyJson.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/LazyJson.cs @@ -3,9 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch; @@ -13,7 +11,7 @@ namespace Elastic.Clients.Elasticsearch; /// Lazily deserializable JSON. /// Holds raw JSON bytes which can be lazily deserialized to a specific using the source serializer at a later time. /// -[JsonConverter(typeof(LazyJsonConverter))] +[JsonConverter(typeof(Json.LazyJsonConverter))] public readonly struct LazyJson { internal LazyJson(byte[] bytes, IElasticsearchClientSettings settings) @@ -39,38 +37,3 @@ internal LazyJson(byte[] bytes, IElasticsearchClientSettings settings) return Settings.SourceSerializer.Deserialize(ms); } } - -internal sealed class LazyJsonConverter : JsonConverter -{ - private IElasticsearchClientSettings _settings; - - public override LazyJson Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - InitializeSettings(options); - - // TODO: fixme -#pragma warning disable IL2026, IL3050 - using var jsonDoc = JsonSerializer.Deserialize(ref reader); -#pragma warning restore IL2026, IL3050 - using var stream = _settings.MemoryStreamFactory.Create(); - - var writer = new Utf8JsonWriter(stream); - jsonDoc.WriteTo(writer); - writer.Flush(); - - return new LazyJson(stream.ToArray(), _settings); - } - - public override void Write(Utf8JsonWriter writer, LazyJson value, JsonSerializerOptions options) => throw new NotImplementedException("We only ever expect to deserialize LazyJson on responses."); - - private void InitializeSettings(JsonSerializerOptions options) - { - if (_settings is null) - { - if (!options.TryGetClientSettings(out var settings)) - ThrowHelper.ThrowJsonExceptionForMissingSettings(); - - _settings = settings; - } - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/LazyJsonConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/LazyJsonConverter.cs new file mode 100644 index 00000000000..d14d41919ab --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/LazyJsonConverter.cs @@ -0,0 +1,46 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class LazyJsonConverter : JsonConverter +{ + private IElasticsearchClientSettings _settings; + + public override LazyJson Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + InitializeSettings(options); + + // TODO: fixme +#pragma warning disable IL2026, IL3050 + using var jsonDoc = JsonSerializer.Deserialize(ref reader); +#pragma warning restore IL2026, IL3050 + using var stream = _settings.MemoryStreamFactory.Create(); + + var writer = new Utf8JsonWriter(stream); + jsonDoc.WriteTo(writer); + writer.Flush(); + + return new LazyJson(stream.ToArray(), _settings); + } + + public override void Write(Utf8JsonWriter writer, LazyJson value, JsonSerializerOptions options) => throw new NotImplementedException("We only ever expect to deserialize LazyJson on responses."); + + private void InitializeSettings(JsonSerializerOptions options) + { + if (_settings is null) + { + if (!options.TryGetClientSettings(out var settings)) + ThrowHelper.ThrowJsonExceptionForMissingSettings(); + + _settings = settings; + } + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/MinimumShouldMatch.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/MinimumShouldMatch.cs index 4d78325d1d5..6bde590288e 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/MinimumShouldMatch.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/MinimumShouldMatch.cs @@ -2,15 +2,11 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; - namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(MinimumShouldMatchConverter))] +[JsonConverter(typeof(Json.MinimumShouldMatchConverter))] public sealed class MinimumShouldMatch : Union { public MinimumShouldMatch(int count) : base(count) @@ -31,33 +27,3 @@ public MinimumShouldMatch(string percentage) : base(percentage) public static implicit operator MinimumShouldMatch(double second) => Percentage(second); } - -internal sealed class MinimumShouldMatchConverter : - JsonConverter -{ - public override MinimumShouldMatch Read(ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) - { - return reader.TokenType switch - { - JsonTokenType.Number => new MinimumShouldMatch(reader.GetInt32()), - JsonTokenType.String => new MinimumShouldMatch(reader.GetString()!), - _ => throw reader.UnexpectedTokenException(JsonTokenType.Number, JsonTokenType.String) - }; - } - - public override void Write(Utf8JsonWriter writer, MinimumShouldMatch value, JsonSerializerOptions options) - { - try - { - value.Match( - writer.WriteNumberValue, - writer.WriteStringValue - ); - } - catch (InvalidOperationException e) - { - throw new JsonException("Invalid union variant.", e); - } - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/MinimumShouldMatchConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/MinimumShouldMatchConverter.cs new file mode 100644 index 00000000000..0ca8ca0df21 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/MinimumShouldMatchConverter.cs @@ -0,0 +1,41 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class MinimumShouldMatchConverter : + JsonConverter +{ + public override MinimumShouldMatch Read(ref Utf8JsonReader reader, Type typeToConvert, + JsonSerializerOptions options) + { + return reader.TokenType switch + { + JsonTokenType.Number => new MinimumShouldMatch(reader.GetInt32()), + JsonTokenType.String => new MinimumShouldMatch(reader.GetString()!), + _ => throw reader.UnexpectedTokenException(JsonTokenType.Number, JsonTokenType.String) + }; + } + + public override void Write(Utf8JsonWriter writer, MinimumShouldMatch value, JsonSerializerOptions options) + { + try + { + value.Match( + writer.WriteNumberValue, + writer.WriteStringValue + ); + } + catch (InvalidOperationException e) + { + throw new JsonException("Invalid union variant.", e); + } + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Number/Number.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Number/Number.cs index 9ffe30eefba..acd69934e19 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Number/Number.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Number/Number.cs @@ -2,20 +2,15 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System; using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; - -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; - namespace Elastic.Clients.Elasticsearch; [DebuggerDisplay("{DebugDisplay,nq}")] -[JsonConverter(typeof(NumberConverter))] +[JsonConverter(typeof(Json.NumberConverter))] public readonly struct Number { private readonly byte _tag; @@ -68,41 +63,3 @@ public bool TryGetDouble(out double value) _ => "" }; } - -internal sealed class NumberConverter : - JsonConverter -{ - public override Number Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.Number); - - if (reader.TryGetDouble(out var d)) - { - return new(d); - } - - if (reader.TryGetInt64(out var l)) - { - return new(l); - } - - throw new JsonException("Could not read JSON value as number."); - } - - public override void Write(Utf8JsonWriter writer, Number value, JsonSerializerOptions options) - { - if (value.TryGetDouble(out var d)) - { - writer.WriteNumberValue(d); - return; - } - - if (value.TryGetLong(out var l)) - { - writer.WriteNumberValue(l); - return; - } - - throw new JsonException($"The '{nameof(Number)}' does not contain a value."); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Number/NumberConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Number/NumberConverter.cs new file mode 100644 index 00000000000..1f938c9395f --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Number/NumberConverter.cs @@ -0,0 +1,49 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class NumberConverter : + JsonConverter +{ + public override Number Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.Number); + + if (reader.TryGetDouble(out var d)) + { + return new(d); + } + + if (reader.TryGetInt64(out var l)) + { + return new(l); + } + + throw new JsonException("Could not read JSON value as number."); + } + + public override void Write(Utf8JsonWriter writer, Number value, JsonSerializerOptions options) + { + if (value.TryGetDouble(out var d)) + { + writer.WriteNumberValue(d); + return; + } + + if (value.TryGetLong(out var l)) + { + writer.WriteNumberValue(l); + return; + } + + throw new JsonException($"The '{nameof(Number)}' does not contain a value."); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/RawJsonString.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/RawJsonString.cs deleted file mode 100644 index 981a9642556..00000000000 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/RawJsonString.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to Elasticsearch B.V under one or more agreements. -// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. -// See the LICENSE file in the project root for more information. - -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Elastic.Clients.Elasticsearch; - -#if NET6_0_OR_GREATER -[JsonConverter(typeof(RawJsonConverter))] -public struct RawJsonString -{ -public RawJsonString(string rawJson) => Json = rawJson; - -public string Json { get; init; } -} - -internal class RawJsonConverter : JsonConverter -{ -public override RawJsonString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException(); -public override void Write(Utf8JsonWriter writer, RawJsonString value, JsonSerializerOptions options) => writer.WriteRawValue(value.Json); -} -#endif diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamName.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamName.cs index 23ee30b7beb..d3daa619588 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamName.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamName.cs @@ -5,14 +5,13 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; + using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(DataStreamNameConverter))] +[JsonConverter(typeof(Json.DataStreamNameConverter))] [DebuggerDisplay("{DebugDisplay,nq}")] public sealed class DataStreamName : IEquatable, @@ -81,23 +80,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class DataStreamNameConverter : JsonConverter -{ - public override DataStreamName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.String); - - return reader.GetString(); - } - - public override void Write(Utf8JsonWriter writer, DataStreamName value, JsonSerializerOptions options) - { - if (value?.Name is null) - { - throw new ArgumentNullException(nameof(value)); - } - - writer.WriteStringValue(value.Name); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNameConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNameConverter.cs new file mode 100644 index 00000000000..07da2cf79ab --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNameConverter.cs @@ -0,0 +1,31 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DataStreamNameConverter : JsonConverter +{ + public override DataStreamName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.String); + + return reader.GetString(); + } + + public override void Write(Utf8JsonWriter writer, DataStreamName value, JsonSerializerOptions options) + { + if (value?.Name is null) + { + throw new ArgumentNullException(nameof(value)); + } + + writer.WriteStringValue(value.Name); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNames.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNames.cs index e78b712c7ff..c0b2dc12014 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNames.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNames.cs @@ -8,15 +8,13 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(DataStreamNamesConverter))] +[JsonConverter(typeof(Json.DataStreamNamesConverter))] [DebuggerDisplay("{DebugDisplay,nq}")] public sealed class DataStreamNames : IUrlParameter, @@ -144,23 +142,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class DataStreamNamesConverter : JsonConverter -{ - public override DataStreamNames Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var fields = reader.ReadCollectionValue(options, null)!; - - return new DataStreamNames(fields); - } - - public override void Write(Utf8JsonWriter writer, DataStreamNames value, JsonSerializerOptions options) - { - if (value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - writer.WriteCollectionValue(options, value.Names, null); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNamesConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNamesConverter.cs new file mode 100644 index 00000000000..862e808c352 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNamesConverter.cs @@ -0,0 +1,31 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class DataStreamNamesConverter : JsonConverter +{ + public override DataStreamNames Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var fields = reader.ReadCollectionValue(options, null)!; + + return new DataStreamNames(fields); + } + + public override void Write(Utf8JsonWriter writer, DataStreamNames value, JsonSerializerOptions options) + { + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + writer.WriteCollectionValue(options, value.Names, null); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/IndexAlias/IndexAlias.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/IndexAlias/IndexAlias.cs index aefd6d71967..f471f6f89b3 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/IndexAlias/IndexAlias.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/IndexAlias/IndexAlias.cs @@ -5,14 +5,13 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using System.Text.Json.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(IndexAliasConverter))] +[JsonConverter(typeof(Json.IndexAliasConverter))] [DebuggerDisplay("{DebugDisplay,nq}")] public class IndexAlias : IEquatable, @@ -81,25 +80,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class IndexAliasConverter : JsonConverter -{ - public override IndexAlias? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.String) - throw new JsonException($"Unexpected token '{reader.TokenType}' for IndexAlias"); - - return reader.GetString(); - } - - public override void Write(Utf8JsonWriter writer, IndexAlias value, JsonSerializerOptions options) - { - if (value is null || value.Alias is null) - { - writer.WriteNullValue(); - return; - } - - writer.WriteStringValue(value.Alias); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/IndexAlias/IndexAliasConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/IndexAlias/IndexAliasConverter.cs new file mode 100644 index 00000000000..01e5d5b9753 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/IndexAlias/IndexAliasConverter.cs @@ -0,0 +1,31 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class IndexAliasConverter : JsonConverter +{ + public override IndexAlias? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) + throw new JsonException($"Unexpected token '{reader.TokenType}' for IndexAlias"); + + return reader.GetString(); + } + + public override void Write(Utf8JsonWriter writer, IndexAlias value, JsonSerializerOptions options) + { + if (value is null || value.Alias is null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStringValue(value.Alias); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Name.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Name.cs index f05de6d0373..48d1e9b7b2e 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Name.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Name.cs @@ -5,16 +5,14 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; [DebuggerDisplay("{DebugDisplay,nq}")] -[JsonConverter(typeof(NameConverter))] +[JsonConverter(typeof(Json.NameConverter))] public sealed class Name : IEquatable, IUrlParameter @@ -85,42 +83,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class NameConverter : - JsonConverter -{ - public override Name? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.String); - - return reader.GetString()!; - } - - public override Name ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.PropertyName); - - return reader.GetString()!; - } - - public override void Write(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) - { - if (value?.Value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - writer.WriteStringValue(value.Value); - } - - public override void WriteAsPropertyName(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) - { - if (value?.Value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - writer.WritePropertyName(value.Value); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/NameConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/NameConverter.cs new file mode 100644 index 00000000000..0cc0e19b268 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/NameConverter.cs @@ -0,0 +1,50 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class NameConverter : + JsonConverter +{ + public override Name? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.String); + + return reader.GetString()!; + } + + public override Name ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, + JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.PropertyName); + + return reader.GetString()!; + } + + public override void Write(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) + { + if (value?.Value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + writer.WriteStringValue(value.Value); + } + + public override void WriteAsPropertyName(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) + { + if (value?.Value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + writer.WritePropertyName(value.Value); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Names.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Names.cs index 56b28a8c905..cd4c8c31179 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Names.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Names.cs @@ -7,16 +7,14 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; [DebuggerDisplay("{DebugDisplay,nq}")] -[JsonConverter(typeof(NamesConverter))] +[JsonConverter(typeof(Json.NamesConverter))] public sealed class Names : IEquatable, IUrlParameter @@ -116,28 +114,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class NamesConverter : - JsonConverter -{ - public override Names Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return reader.TokenType switch - { - JsonTokenType.String => new Names([reader.ReadValue(options)]), - JsonTokenType.StartArray => new Names(reader.ReadValue>(options)), - _ => throw reader.UnexpectedTokenException(JsonTokenType.String, JsonTokenType.StartArray) - }; - } - - public override void Write(Utf8JsonWriter writer, Names value, JsonSerializerOptions options) - { - if (value.Values is [{ } single]) - { - writer.WriteValue(options, single); - return; - } - - writer.WriteValue(options, value.Values); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/NamesConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/NamesConverter.cs new file mode 100644 index 00000000000..8f9bba124eb --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/NamesConverter.cs @@ -0,0 +1,37 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class NamesConverter : + JsonConverter +{ + public override Names Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return reader.TokenType switch + { + JsonTokenType.String => new Names([reader.ReadValue(options)]), + JsonTokenType.StartArray => new Names(reader.ReadValue>(options)), + _ => throw reader.UnexpectedTokenException(JsonTokenType.String, JsonTokenType.StartArray) + }; + } + + public override void Write(Utf8JsonWriter writer, Names value, JsonSerializerOptions options) + { + if (value.Values is [{ } single]) + { + writer.WriteValue(options, single); + return; + } + + writer.WriteValue(options, value.Values); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollId.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollId.cs index 13a4ca216fe..87c8dbafcb7 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollId.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollId.cs @@ -5,14 +5,13 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using System.Text.Json.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(ScrollIdConverter))] +[JsonConverter(typeof(Json.ScrollIdConverter))] [DebuggerDisplay("{DebugDisplay,nq}")] public sealed class ScrollId : IEquatable, @@ -81,25 +80,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class ScrollIdConverter : JsonConverter -{ - public override ScrollId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.String) - throw new JsonException($"Unexpected token '{reader.TokenType}' for DataStreamName"); - - return reader.GetString(); - } - - public override void Write(Utf8JsonWriter writer, ScrollId value, JsonSerializerOptions options) - { - if (value is null || value.Id is null) - { - writer.WriteNullValue(); - return; - } - - writer.WriteStringValue(value.Id); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIdConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIdConverter.cs new file mode 100644 index 00000000000..4c2eca5ea2b --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIdConverter.cs @@ -0,0 +1,31 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class ScrollIdConverter : JsonConverter +{ + public override ScrollId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.String) + throw new JsonException($"Unexpected token '{reader.TokenType}' for DataStreamName"); + + return reader.GetString(); + } + + public override void Write(Utf8JsonWriter writer, ScrollId value, JsonSerializerOptions options) + { + if (value is null || value.Id is null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStringValue(value.Id); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIds.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIds.cs index c32ef7ead6e..d091a7d3985 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIds.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIds.cs @@ -8,15 +8,13 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(ScrollIdsConverter))] +[JsonConverter(typeof(Json.ScrollIdsConverter))] [DebuggerDisplay("{DebugDisplay,nq}")] public sealed class ScrollIds : IUrlParameter, @@ -143,28 +141,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class ScrollIdsConverter : - JsonConverter -{ - public override ScrollIds Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return reader.TokenType switch - { - JsonTokenType.String => new ScrollIds([reader.ReadValue(options)]), - JsonTokenType.StartArray => new ScrollIds(reader.ReadValue>(options)), - _ => throw new JsonException($"Expected JSON '{JsonTokenType.String}' or '{JsonTokenType.StartArray}' token, but got '{reader.TokenType}'.") - }; - } - - public override void Write(Utf8JsonWriter writer, ScrollIds value, JsonSerializerOptions options) - { - if (value.Ids.Count == 1) - { - writer.WriteValue(options, value.Ids[0]); - return; - } - - writer.WriteValue(options, value.Ids); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIdsConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIdsConverter.cs new file mode 100644 index 00000000000..82630beb59b --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/ScrollIds/ScrollIdsConverter.cs @@ -0,0 +1,37 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class ScrollIdsConverter : + JsonConverter +{ + public override ScrollIds Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return reader.TokenType switch + { + JsonTokenType.String => new ScrollIds([reader.ReadValue(options)]), + JsonTokenType.StartArray => new ScrollIds(reader.ReadValue>(options)), + _ => throw new JsonException($"Expected JSON '{JsonTokenType.String}' or '{JsonTokenType.StartArray}' token, but got '{reader.TokenType}'.") + }; + } + + public override void Write(Utf8JsonWriter writer, ScrollIds value, JsonSerializerOptions options) + { + if (value.Ids.Count == 1) + { + writer.WriteValue(options, value.Ids[0]); + return; + } + + writer.WriteValue(options, value.Ids); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/TaskId/TaskId.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/TaskId/TaskId.cs index bc57a747576..d032feee97a 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/TaskId/TaskId.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/TaskId/TaskId.cs @@ -6,15 +6,13 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(TaskIdConverter))] +[JsonConverter(typeof(Json.TaskIdConverter))] [DebuggerDisplay("{DebugDisplay,nq}")] public sealed class TaskId : IUrlParameter, @@ -105,41 +103,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class TaskIdConverter : JsonConverter -{ - public override void WriteAsPropertyName(Utf8JsonWriter writer, TaskId value, JsonSerializerOptions options) - { - if (options.TryGetClientSettings(out var settings)) - { - writer.WritePropertyName(((IUrlParameter)value).GetString(settings)); - return; - } - - throw new JsonException("Unable to retrive client settings during property name serialization."); - } - - public override TaskId ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetString(); - - public override TaskId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Null) - return null; - - if (reader.TokenType == JsonTokenType.String) - { - var taskId = reader.GetString(); - return new TaskId(taskId); - } - - throw new JsonException("Unexpected JSON token"); - } - - public override void Write(Utf8JsonWriter writer, TaskId value, JsonSerializerOptions options) - { - if (value is null) - writer.WriteNullValue(); - - writer.WriteStringValue(value.FullyQualifiedId); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/TaskId/TaskIdConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/TaskId/TaskIdConverter.cs new file mode 100644 index 00000000000..faecfc05f16 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/TaskId/TaskIdConverter.cs @@ -0,0 +1,50 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; +using Elastic.Transport; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class TaskIdConverter : JsonConverter +{ + public override void WriteAsPropertyName(Utf8JsonWriter writer, TaskId value, JsonSerializerOptions options) + { + if (options.TryGetClientSettings(out var settings)) + { + writer.WritePropertyName(((IUrlParameter)value).GetString(settings)); + return; + } + + throw new JsonException("Unable to retrive client settings during property name serialization."); + } + + public override TaskId ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => reader.GetString(); + + public override TaskId? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + return null; + + if (reader.TokenType == JsonTokenType.String) + { + var taskId = reader.GetString(); + return new TaskId(taskId); + } + + throw new JsonException("Unexpected JSON token"); + } + + public override void Write(Utf8JsonWriter writer, TaskId value, JsonSerializerOptions options) + { + if (value is null) + writer.WriteNullValue(); + + writer.WriteStringValue(value.FullyQualifiedId); + } +} 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 6333625e868..be278fb609b 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/Username.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/Username.cs @@ -5,16 +5,14 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; [DebuggerDisplay("{DebugDisplay,nq}")] -[JsonConverter(typeof(UsernameConverter))] +[JsonConverter(typeof(Json.UsernameConverter))] public class Username : IEquatable, IUrlParameter @@ -77,42 +75,3 @@ public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? prov #endregion IParsable } - -internal sealed class UsernameConverter : - JsonConverter -{ - public override Username? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.String); - - return reader.GetString()!; - } - - public override Username ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.PropertyName); - - return reader.GetString()!; - } - - public override void Write(Utf8JsonWriter writer, Username value, JsonSerializerOptions options) - { - if (value?.Value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - writer.WriteStringValue(value.Value); - } - - public override void WriteAsPropertyName(Utf8JsonWriter writer, Username value, JsonSerializerOptions options) - { - if (value?.Value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - writer.WritePropertyName(value.Value); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/UsernameConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/UsernameConverter.cs new file mode 100644 index 00000000000..cfe85b9e502 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Username/UsernameConverter.cs @@ -0,0 +1,50 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public sealed class UsernameConverter : + JsonConverter +{ + public override Username? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.String); + + return reader.GetString()!; + } + + public override Username ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, + JsonSerializerOptions options) + { + reader.ValidateToken(JsonTokenType.PropertyName); + + return reader.GetString()!; + } + + public override void Write(Utf8JsonWriter writer, Username value, JsonSerializerOptions options) + { + if (value?.Value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + writer.WriteStringValue(value.Value); + } + + public override void WriteAsPropertyName(Utf8JsonWriter writer, Username value, JsonSerializerOptions options) + { + if (value?.Value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + writer.WritePropertyName(value.Value); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs index 84d1820993e..65b62c9f604 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; @@ -37,13 +38,13 @@ public ContextProvider(TContext context) [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public static TContext GetContext(JsonSerializerOptions options) { - if (options.GetConverter(typeof(Marker)) is not Converter provider) + if (!TryGetContext(options, out var context)) { - throw new InvalidOperationException($"No context provider for type '{typeof(TContext).Name}' is " + - $"registered for the given 'JsonSerializerOptions' instance."); + throw new InvalidOperationException( + $"No context provider for type '{typeof(TContext).Name}' is registered for the given 'JsonSerializerOptions' instance."); } - return provider.Context; + return context; } /// @@ -59,6 +60,12 @@ public static TContext GetContext(JsonSerializerOptions options) [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public static bool TryGetContext(JsonSerializerOptions options, [MaybeNullWhen(false)] out TContext context) { + if (options.Converters.FirstOrDefault(x => x.CanConvert(typeof(Marker))) is ContextProvider global) + { + context = global._converter.Context; + return true; + } + if (options.GetConverter(typeof(Marker)) is not Converter provider) { context = default; @@ -71,7 +78,7 @@ public static bool TryGetContext(JsonSerializerOptions options, [MaybeNullWhen(f public override bool CanConvert(Type typeToConvert) { - return typeToConvert == typeof(Marker); + return (typeToConvert == typeof(Marker)); } public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/EnumStructConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/EnumStructConverter.cs deleted file mode 100644 index e2570641c0f..00000000000 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Next/EnumStructConverter.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to Elasticsearch B.V under one or more agreements. -// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. -// See the LICENSE file in the project root for more information. - -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Elastic.Clients.Elasticsearch.Serialization; - -internal sealed class EnumStructConverter : - JsonConverter - where T : struct, IEnumStruct -{ - public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - reader.ValidateToken(JsonTokenType.String); - - var value = reader.GetString()!; - -#if NET7_0_OR_GREATER - var result = T.Create(value); -#else - var result = default(T).Create(value); -#endif - - return result; - } - - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) - { - if (!string.IsNullOrEmpty(value.Value)) - { - writer.WriteStringValue(value.Value); - } - else - { - writer.WriteNullValue(); - } - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/JsonIncompatibleConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/JsonIncompatibleConverter.cs new file mode 100644 index 00000000000..533e8257274 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Next/JsonIncompatibleConverter.cs @@ -0,0 +1,27 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Serialization; + +/// +/// A implementation that is used to indicate that a type is not compatible with +/// standard JSON serialization. +/// +internal sealed class JsonIncompatibleConverter : + JsonConverterFactory +{ + public override bool CanConvert(Type typeToConvert) + { + return true; + } + + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + throw new NotSupportedException($"Type '{typeToConvert.FullName}' is not compatible with standard JSON serialization."); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/RequestResponseConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/RequestResponseConverter.cs index 23f73518d47..952dbd8d3a0 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Next/RequestResponseConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Next/RequestResponseConverter.cs @@ -13,6 +13,11 @@ namespace Elastic.Clients.Elasticsearch.Serialization; public sealed class RequestResponseConverter : JsonConverter { + public override bool CanConvert(Type typeToConvert) + { + return (typeToConvert == typeof(T)); + } + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var settings = options.GetContext(); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Serialization/DefaultRequestResponseSerializer.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Serialization/DefaultRequestResponseSerializer.cs index 193931f45d7..14aaef49913 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Serialization/DefaultRequestResponseSerializer.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Serialization/DefaultRequestResponseSerializer.cs @@ -63,6 +63,7 @@ public override T Deserialize(Stream stream) { if (typeof(IStreamSerializable).IsAssignableFrom(typeof(T))) { + throw new NotSupportedException("Deserialization of 'IStreamSerializable' types is currently not supported."); } return base.Deserialize(stream); @@ -72,6 +73,7 @@ public override T Deserialize(Stream stream) { if (typeof(IStreamSerializable).IsAssignableFrom(type)) { + throw new NotSupportedException("Deserialization of 'IStreamSerializable' types is currently not supported."); } return base.Deserialize(type, stream); @@ -81,6 +83,7 @@ public override ValueTask DeserializeAsync(Stream stream, CancellationToke { if (typeof(IStreamSerializable).IsAssignableFrom(typeof(T))) { + throw new NotSupportedException("Deserialization of 'IStreamSerializable' types is currently not supported."); } return base.DeserializeAsync(stream, cancellationToken); @@ -90,6 +93,7 @@ public override ValueTask DeserializeAsync(Stream stream, CancellationToke { if (typeof(IStreamSerializable).IsAssignableFrom(type)) { + throw new NotSupportedException("Deserialization of 'IStreamSerializable' types is currently not supported."); } return base.DeserializeAsync(type, stream, cancellationToken); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/BucketsPath.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/BucketsPath.cs index c44849da3e2..15dd9aef135 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/BucketsPath.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/BucketsPath.cs @@ -4,21 +4,18 @@ #nullable enable -using Elastic.Clients.Elasticsearch.Core; - -using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; + +using Elastic.Clients.Elasticsearch.Core; namespace Elastic.Clients.Elasticsearch.Aggregations; /// /// Buckets path can be expressed in different ways, and an aggregation may accept some or all of these
forms depending on its type. Please refer to each aggregation's documentation to know what buckets
path forms they accept.
///
-[JsonConverter(typeof(BucketsPathConverter))] +[JsonConverter(typeof(Json.BucketsPathConverter))] public sealed class BucketsPath : IComplexUnion { public enum Kind @@ -95,39 +92,3 @@ public bool TryGetDictionary([NotNullWhen(true)] out Dictionary? public static implicit operator BucketsPath(Dictionary dictionary) => BucketsPath.Dictionary(dictionary); } - -internal sealed class BucketsPathConverter : JsonConverter -{ - public override BucketsPath? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return (reader.TokenType) switch - { - JsonTokenType.Null => null, - JsonTokenType.String => BucketsPath.Single(reader.ReadValue(options)!), - JsonTokenType.StartArray => BucketsPath.Array(reader.ReadCollectionValue(options, null)!.ToArray()), - JsonTokenType.StartObject => BucketsPath.Dictionary(reader.ReadDictionaryValue(options, null, null)!), - _ => throw new JsonException($"Unexpected token '{reader.TokenType}'.") - }; - } - - public override void Write(Utf8JsonWriter writer, BucketsPath value, JsonSerializerOptions options) - { - switch (value._kind) - { - case BucketsPath.Kind.Single: - writer.WriteStringValue((string)value._value); - break; - - case BucketsPath.Kind.Array: - writer.WriteCollectionValue(options, (string[])value._value, null); - break; - - case BucketsPath.Kind.Dictionary: - writer.WriteDictionaryValue(options, (Dictionary)value._value, null, null); - break; - - default: - throw new ArgumentOutOfRangeException(); - } - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/BucketsPathConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/BucketsPathConverter.cs new file mode 100644 index 00000000000..09c0caa1f7a --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/BucketsPathConverter.cs @@ -0,0 +1,50 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Aggregations.Json; + +public sealed class BucketsPathConverter : JsonConverter +{ + public override BucketsPath? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return (reader.TokenType) switch + { + JsonTokenType.Null => null, + JsonTokenType.String => BucketsPath.Single(reader.ReadValue(options)!), + JsonTokenType.StartArray => BucketsPath.Array(reader.ReadCollectionValue(options, null)!.ToArray()), + JsonTokenType.StartObject => BucketsPath.Dictionary(reader.ReadDictionaryValue(options, null, null)!), + _ => throw new JsonException($"Unexpected token '{reader.TokenType}'.") + }; + } + + public override void Write(Utf8JsonWriter writer, BucketsPath value, JsonSerializerOptions options) + { + switch (value._kind) + { + case BucketsPath.Kind.Single: + writer.WriteStringValue((string)value._value); + break; + + case BucketsPath.Kind.Array: + writer.WriteCollectionValue(options, (string[])value._value, null); + break; + + case BucketsPath.Kind.Dictionary: + writer.WriteDictionaryValue(options, (Dictionary)value._value, null, null); + break; + + default: + throw new ArgumentOutOfRangeException(); + } + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsExclude.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsExclude.cs index f6dd968f7d1..87ad3a2babc 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsExclude.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsExclude.cs @@ -2,21 +2,18 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; - -#nullable enable - namespace Elastic.Clients.Elasticsearch.Aggregations; /// /// Filters which terms to exclude from the response. /// -[JsonConverter(typeof(TermsExcludeConverter))] +[JsonConverter(typeof(Json.TermsExcludeConverter))] public sealed class TermsExclude { /// @@ -55,33 +52,3 @@ public TermsExclude(IEnumerable values) /// public IEnumerable? Values { get; } } - -internal sealed class TermsExcludeConverter : JsonConverter -{ - public override TermsExclude Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return reader.TokenType switch - { - JsonTokenType.StartArray => new TermsExclude(reader.ReadCollectionValue(options, null)!), - JsonTokenType.String => new TermsExclude(reader.ReadValue(options)!), - _ => throw new JsonException( - $"Unexpected token {reader.TokenType} when deserializing {nameof(TermsExclude)}") - }; - } - - public override void Write(Utf8JsonWriter writer, TermsExclude value, JsonSerializerOptions options) - { - if (value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - if (value.Values is not null) - { - writer.WriteCollectionValue(options, value.Values, null); - return; - } - - writer.WriteStringValue(value.RegexPattern); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsExcludeConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsExcludeConverter.cs new file mode 100644 index 00000000000..8ebd505acd6 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsExcludeConverter.cs @@ -0,0 +1,43 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Aggregations.Json; + +public sealed class TermsExcludeConverter : JsonConverter +{ + public override TermsExclude Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return reader.TokenType switch + { + JsonTokenType.StartArray => new TermsExclude(reader.ReadCollectionValue(options, null)!), + JsonTokenType.String => new TermsExclude(reader.ReadValue(options)!), + _ => throw new JsonException( + $"Unexpected token {reader.TokenType} when deserializing {nameof(TermsExclude)}") + }; + } + + public override void Write(Utf8JsonWriter writer, TermsExclude value, JsonSerializerOptions options) + { + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (value.Values is not null) + { + writer.WriteCollectionValue(options, value.Values, null); + return; + } + + writer.WriteStringValue(value.RegexPattern); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsInclude.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsInclude.cs index eac0bbdb519..54ae2cbf5fd 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsInclude.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsInclude.cs @@ -2,21 +2,18 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; - -#nullable enable - namespace Elastic.Clients.Elasticsearch.Aggregations; /// /// Filters which terms to include in the response. /// -[JsonConverter(typeof(TermsIncludeConverter))] +[JsonConverter(typeof(Json.TermsIncludeConverter))] public class TermsInclude { /// @@ -77,74 +74,3 @@ public TermsInclude(long partition, long numberOfPartitions) /// public IEnumerable? Values { get; } } - -internal sealed class TermsIncludeConverter : JsonConverter -{ - public override TermsInclude? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - switch (reader.TokenType) - { - case JsonTokenType.StartArray: - return new TermsInclude(reader.ReadCollectionValue(options, null)!); - - case JsonTokenType.StartObject: - long partition = 0; - long numberOfPartitions = 0; - while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) - { - if (reader.TokenType == JsonTokenType.PropertyName) - { - var propertyName = reader.GetString(); - reader.Read(); - switch (propertyName) - { - case "partition": - partition = reader.GetInt64(); - break; - - case "num_partitions": - numberOfPartitions = reader.GetInt64(); - break; - - default: - throw new JsonException($"Unexpected property name '{propertyName}' encountered when deserializing TermsInclude."); - } - } - } - return new TermsInclude(partition, numberOfPartitions); - - case JsonTokenType.String: - return new TermsInclude(reader.ReadValue(options)!); - - default: - throw new JsonException($"Unexpected token {reader.TokenType} when deserializing {nameof(TermsInclude)}"); - } - } - - public override void Write(Utf8JsonWriter writer, TermsInclude value, JsonSerializerOptions options) - { - if (value is null) - { - throw new ArgumentNullException(nameof(value)); - } - - if (value.Values is not null) - { - writer.WriteCollectionValue(options, value.Values, null); - return; - } - - if (value.Partition.HasValue && value.NumberOfPartitions.HasValue) - { - writer.WriteStartObject(); - writer.WritePropertyName("partition"); - writer.WriteNumberValue(value.Partition.Value); - writer.WritePropertyName("num_partitions"); - writer.WriteNumberValue(value.NumberOfPartitions.Value); - writer.WriteEndObject(); - return; - } - - writer.WriteStringValue(value.RegexPattern); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsIncludeConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsIncludeConverter.cs new file mode 100644 index 00000000000..bedf3bb8619 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Aggregations/TermsIncludeConverter.cs @@ -0,0 +1,84 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +#nullable enable + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Aggregations.Json; + +public sealed class TermsIncludeConverter : JsonConverter +{ + public override TermsInclude? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + switch (reader.TokenType) + { + case JsonTokenType.StartArray: + return new TermsInclude(reader.ReadCollectionValue(options, null)!); + + case JsonTokenType.StartObject: + long partition = 0; + long numberOfPartitions = 0; + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = reader.GetString(); + reader.Read(); + switch (propertyName) + { + case "partition": + partition = reader.GetInt64(); + break; + + case "num_partitions": + numberOfPartitions = reader.GetInt64(); + break; + + default: + throw new JsonException($"Unexpected property name '{propertyName}' encountered when deserializing TermsInclude."); + } + } + } + return new TermsInclude(partition, numberOfPartitions); + + case JsonTokenType.String: + return new TermsInclude(reader.ReadValue(options)!); + + default: + throw new JsonException($"Unexpected token {reader.TokenType} when deserializing {nameof(TermsInclude)}"); + } + } + + public override void Write(Utf8JsonWriter writer, TermsInclude value, JsonSerializerOptions options) + { + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } + + if (value.Values is not null) + { + writer.WriteCollectionValue(options, value.Values, null); + return; + } + + if (value.Partition.HasValue && value.NumberOfPartitions.HasValue) + { + writer.WriteStartObject(); + writer.WritePropertyName("partition"); + writer.WriteNumberValue(value.Partition.Value); + writer.WritePropertyName("num_partitions"); + writer.WriteNumberValue(value.NumberOfPartitions.Value); + writer.WriteEndObject(); + return; + } + + writer.WriteStringValue(value.RegexPattern); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkCreateOperation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkCreateOperation.cs index 40bf512bb9f..ea6cf818d71 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkCreateOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkCreateOperation.cs @@ -17,6 +17,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; /// Represents a bulk operation to create a document. ///
/// The type representing the document being created. +[JsonConverter(typeof(JsonIncompatibleConverter))] public sealed class BulkCreateOperation : BulkOperation { private static readonly System.Text.Json.JsonEncodedText PropDynamicTemplates = System.Text.Json.JsonEncodedText.Encode("dynamic_templates"); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkDeleteOperation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkDeleteOperation.cs index f2a59fec5a8..dcf2e7f92e6 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkDeleteOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkDeleteOperation.cs @@ -12,6 +12,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; +[JsonConverter(typeof(JsonIncompatibleConverter))] public class BulkDeleteOperation : BulkOperation { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkIndexOperation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkIndexOperation.cs index 80c424861fe..2a5e665a2d5 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkIndexOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkIndexOperation.cs @@ -6,12 +6,15 @@ using System.Collections.Generic; using System.IO; using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; -using Elastic.Transport.Extensions; + using Elastic.Clients.Elasticsearch.Serialization; +using Elastic.Transport.Extensions; namespace Elastic.Clients.Elasticsearch.Core.Bulk; +[JsonConverter(typeof(JsonIncompatibleConverter))] public sealed class BulkIndexOperation : BulkOperation { private static readonly System.Text.Json.JsonEncodedText PropDynamicTemplates = System.Text.Json.JsonEncodedText.Encode("dynamic_templates"); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperation.cs index 66da03aa485..64176224271 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperation.cs @@ -18,6 +18,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; /// /// This is an abstract class. /// +[JsonConverter(typeof(JsonIncompatibleConverter))] public abstract class BulkOperation : IBulkOperation, IStreamSerializable diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperationsCollection.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperationsCollection.cs index 80cc7e01cdb..909e8a3aa32 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperationsCollection.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkOperationsCollection.cs @@ -6,20 +6,19 @@ using System.Collections; using System.Collections.Generic; using System.IO; +using System.Text.Json.Serialization; using System.Threading.Tasks; + using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -///// -///// This class is used by which needs thread-safe adding , as well as expose -///// an equivalent of . Because operations from Elasticsearch are executed in order none of the types in -///// System.Collection.Concurrent can be used for this. We need to preserve insert order and exposed indexed index because -///// is ordered and lines up with allowing one to zip the two together. -///// -///// -public sealed class BulkOperationsCollection : IList, IList, IStreamSerializable +[JsonConverter(typeof(JsonIncompatibleConverter))] +public sealed class BulkOperationsCollection : + IList, + IList, + IStreamSerializable { private readonly object _lock = new(); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkResponseItemConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkResponseItemConverter.cs index 380a81df2f7..00eddbfde89 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkResponseItemConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkResponseItemConverter.cs @@ -8,9 +8,9 @@ using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch.Core.Bulk; +namespace Elastic.Clients.Elasticsearch.Core.Bulk.Json; -internal sealed class BulkResponseItemConverter : JsonConverter +public sealed class BulkResponseItemConverter : JsonConverter { private static readonly JsonEncodedText PropError = JsonEncodedText.Encode("error"); private static readonly JsonEncodedText PropForcedRefresh = JsonEncodedText.Encode("forced_refresh"); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperation.cs index d6c19e053c3..f8bb93c6627 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperation.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; using Elastic.Clients.Elasticsearch.Serialization; @@ -12,6 +13,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; +[JsonConverter(typeof(JsonIncompatibleConverter))] public abstract class BulkUpdateOperation : BulkOperation { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationT.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationT.cs index 117221be687..a5ee7b99b63 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationT.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationT.cs @@ -4,11 +4,14 @@ using System; using System.Linq; +using System.Text.Json.Serialization; using Elastic.Clients.Elasticsearch.Core.Search; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; +[JsonConverter(typeof(JsonIncompatibleConverter))] public sealed class BulkUpdateOperation : BulkUpdateOperation { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs index c17c681aafb..86b07bf1ca5 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs @@ -3,9 +3,13 @@ // See the LICENSE file in the project root for more information. using System; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; +[JsonConverter(typeof(JsonIncompatibleConverter))] public sealed class BulkUpdateOperationWithPartial : BulkUpdateOperation { public BulkUpdateOperationWithPartial(Id id, TPartialDocument partialDocument) diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithScript.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithScript.cs index ee57a72c935..55230787c6c 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithScript.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Bulk/BulkUpdateOperationWithScript.cs @@ -3,9 +3,13 @@ // See the LICENSE file in the project root for more information. using System; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; +[JsonConverter(typeof(JsonIncompatibleConverter))] public class BulkUpdateOperationWithScript : BulkUpdateOperation { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearch/SearchRequestItem.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearch/SearchRequestItem.cs index 906b581163b..4cce57ed649 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearch/SearchRequestItem.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearch/SearchRequestItem.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.IO; +using System.Text.Json.Serialization; using System.Threading.Tasks; using Elastic.Clients.Elasticsearch.Serialization; @@ -11,7 +12,10 @@ namespace Elastic.Clients.Elasticsearch.Core.MSearch; // POC - If we have more than one union doing this, can we autogenerate with correct ctors etc. -public sealed class SearchRequestItem : IStreamSerializable + +[JsonConverter(typeof(JsonIncompatibleConverter))] +public sealed class SearchRequestItem : + IStreamSerializable { public SearchRequestItem(MultisearchBody body) => Body = body; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearchTemplate/SearchTemplateRequestItem.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearchTemplate/SearchTemplateRequestItem.cs index 10a089a4262..cf454f95806 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearchTemplate/SearchTemplateRequestItem.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/MSearchTemplate/SearchTemplateRequestItem.cs @@ -3,16 +3,18 @@ // See the LICENSE file in the project root for more information. using System.IO; -using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; + using Elastic.Clients.Elasticsearch.Core.MSearch; using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; -using Elastic.Transport.Extensions; namespace Elastic.Clients.Elasticsearch.Core.MSearchTemplate; -public sealed class SearchTemplateRequestItem : IStreamSerializable +[JsonConverter(typeof(JsonIncompatibleConverter))] +public sealed class SearchTemplateRequestItem : + IStreamSerializable { public SearchTemplateRequestItem(TemplateConfig body) => Body = body; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs index 10ecb87b245..c121e377488 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBounds.cs @@ -2,115 +2,11 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System; - -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; - namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(GeoBoundsConverter))] +[JsonConverter(typeof(Json.GeoBoundsConverter))] 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) - { - 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) - { - if (value.TryGetCoordinates(out var coordinates)) - { - writer.WriteValue(options, coordinates); - return; - } - - if (value.TryGetTopLeftBottomRight(out var topLeftBottomRight)) - { - writer.WriteValue(options, topLeftBottomRight); - return; - } - - if (value.TryGetTopRightBottomLeft(out var topRightBottomLeft)) - { - writer.WriteValue(options, topRightBottomLeft); - return; - } - - if (value.TryGetWkt(out var wkt)) - { - writer.WriteValue(options, wkt); - return; - } - - throw new JsonException($"Unrecognized '{typeof(GeoBounds)}' variant."); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBoundsConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBoundsConverter.cs new file mode 100644 index 00000000000..6d8658a584f --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoBoundsConverter.cs @@ -0,0 +1,111 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; + +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public 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) + { + 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) + { + if (value.TryGetCoordinates(out var coordinates)) + { + writer.WriteValue(options, coordinates); + return; + } + + if (value.TryGetTopLeftBottomRight(out var topLeftBottomRight)) + { + writer.WriteValue(options, topLeftBottomRight); + return; + } + + if (value.TryGetTopRightBottomLeft(out var topRightBottomLeft)) + { + writer.WriteValue(options, topRightBottomLeft); + return; + } + + if (value.TryGetWkt(out var wkt)) + { + writer.WriteValue(options, wkt); + return; + } + + throw new JsonException($"Unrecognized '{typeof(GeoBounds)}' variant."); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs index ab2829f04fa..1a75e6c3fb1 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocation.cs @@ -2,105 +2,14 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; - namespace Elastic.Clients.Elasticsearch; -[JsonConverter(typeof(GeoLocationConverter))] +[JsonConverter(typeof(Json.GeoLocationConverter))] public partial class GeoLocation { public static bool IsValidLatitude(double latitude) => latitude >= -90 && latitude <= 90; public static bool IsValidLongitude(double longitude) => longitude >= -180 && longitude <= 180; } - -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) - { - 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) - { - if (value.TryGetCoordinates(out var coordinates)) - { - writer.WriteCollectionValue(options, coordinates, null); - return; - } - - if (value.TryGetGeoHash(out var geoHash)) - { - writer.WriteValue(options, geoHash); - return; - } - - if (value.TryGetLatitudeLongitude(out var latitudeLongitude)) - { - writer.WriteValue(options, latitudeLongitude); - return; - } - - if (value.TryGetText(out var text)) - { - writer.WriteValue(options, text); - return; - } - - throw new JsonException($"Unrecognized '{typeof(GeoLocation)}' variant."); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocationConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocationConverter.cs new file mode 100644 index 00000000000..91b3aa66089 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/GeoLocationConverter.cs @@ -0,0 +1,98 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Json; + +public 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) + { + 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) + { + if (value.TryGetCoordinates(out var coordinates)) + { + writer.WriteCollectionValue(options, coordinates, null); + return; + } + + if (value.TryGetGeoHash(out var geoHash)) + { + writer.WriteValue(options, geoHash); + return; + } + + if (value.TryGetLatitudeLongitude(out var latitudeLongitude)) + { + writer.WriteValue(options, latitudeLongitude); + return; + } + + if (value.TryGetText(out var text)) + { + writer.WriteValue(options, text); + return; + } + + throw new JsonException($"Unrecognized '{typeof(GeoLocation)}' variant."); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Mapping/Properties.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Mapping/Properties.cs index 9e3d6f12da9..e2df868cae5 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Mapping/Properties.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Mapping/Properties.cs @@ -4,13 +4,11 @@ using System; using System.Linq.Expressions; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Mapping; -[JsonConverter(typeof(PropertiesConverter))] +[JsonConverter(typeof(Json.PropertiesConverter))] public partial class Properties { private readonly IElasticsearchClientSettings _settings; @@ -22,59 +20,6 @@ public partial class Properties protected override PropertyName Sanitize(PropertyName key) => _settings?.Inferrer.PropertyName(key) ?? key; } -internal sealed class PropertiesConverter : JsonConverter -{ - public override Properties? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (!options.TryGetClientSettings(out var settings)) - ThrowHelper.ThrowJsonExceptionForMissingSettings(); - - if (reader.TokenType != JsonTokenType.StartObject) - throw new JsonException("Expected start object token."); - - var properties = new Properties(settings); - - while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) - { - if (reader.TokenType != JsonTokenType.PropertyName) - throw new JsonException("Expected property name token."); - - var propertyName = reader.GetString(); - reader.Read(); - var property = reader.ReadValue(options); - properties.Add(propertyName, property); - } - - return properties; - } - - public override void Write(Utf8JsonWriter writer, Properties value, JsonSerializerOptions options) - { - if (!options.TryGetClientSettings(out var settings)) - ThrowHelper.ThrowJsonExceptionForMissingSettings(); - - if (value is null) - { - writer.WriteNullValue(); - return; - } - - // HACK: Deduplicate property mappings with an instance of Properties that has access to ElasticsearchClientSettings to sanitize PropertyName keys. - var properties = new Properties(settings); - - foreach (var kv in value) - { - // TODO - NEST checks for properties of IPropertyWithClrOrigin so that it can then skip ignored properties etc. - // This functionality is missing for GA. - - properties[kv.Key] = kv.Value; - continue; - } - - writer.WriteDictionaryValue(options, properties.BackingDictionary, null, null); - } -} - public sealed class Properties : Properties { public void Add(Expression> name, IProperty property) => BackingDictionary.Add(name, property); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Mapping/PropertiesConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Mapping/PropertiesConverter.cs new file mode 100644 index 00000000000..9ea912e4560 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Mapping/PropertiesConverter.cs @@ -0,0 +1,64 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Mapping.Json; + +public sealed class PropertiesConverter : JsonConverter +{ + public override Properties? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (!options.TryGetClientSettings(out var settings)) + ThrowHelper.ThrowJsonExceptionForMissingSettings(); + + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Expected start object token."); + + var properties = new Properties(settings); + + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType != JsonTokenType.PropertyName) + throw new JsonException("Expected property name token."); + + var propertyName = reader.GetString(); + reader.Read(); + var property = reader.ReadValue(options); + properties.Add(propertyName, property); + } + + return properties; + } + + public override void Write(Utf8JsonWriter writer, Properties value, JsonSerializerOptions options) + { + if (!options.TryGetClientSettings(out var settings)) + ThrowHelper.ThrowJsonExceptionForMissingSettings(); + + if (value is null) + { + writer.WriteNullValue(); + return; + } + + // HACK: Deduplicate property mappings with an instance of Properties that has access to ElasticsearchClientSettings to sanitize PropertyName keys. + var properties = new Properties(settings); + + foreach (var kv in value) + { + // TODO - NEST checks for properties of IPropertyWithClrOrigin so that it can then skip ignored properties etc. + // This functionality is missing for GA. + + properties[kv.Key] = kv.Value; + continue; + } + + writer.WriteDictionaryValue(options, properties.BackingDictionary, null, null); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlRow.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlRow.cs index af039b96505..1290c00ba1d 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlRow.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlRow.cs @@ -2,46 +2,16 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Sql; -[JsonConverter(typeof(SqlRowConverter))] +[JsonConverter(typeof(Json.SqlRowConverter))] public sealed class SqlRow : ReadOnlyCollection { - public SqlRow(IList list) : base(list) { } -} - -internal sealed class SqlRowConverter : JsonConverter -{ - public override SqlRow? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public SqlRow(IList list) : base(list) { - if (reader.TokenType == JsonTokenType.Null) - { - reader.Read(); - return null; - } - - if (reader.TokenType == JsonTokenType.StartArray) - { - var values = new List(); - - while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) - { - var value = reader.ReadValue(options); - values.Add(value); - } - - return new SqlRow(values); - } - - throw new JsonException($"Unexpected JSON token when deserializing {nameof(SqlRow)}."); } - - public override void Write(Utf8JsonWriter writer, SqlRow value, JsonSerializerOptions options) => throw new NotImplementedException(); } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlRowConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlRowConverter.cs new file mode 100644 index 00000000000..46b39a310ed --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlRowConverter.cs @@ -0,0 +1,41 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Sql.Json; + +public sealed class SqlRowConverter : JsonConverter +{ + public override SqlRow? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + reader.Read(); + return null; + } + + if (reader.TokenType == JsonTokenType.StartArray) + { + var values = new List(); + + while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) + { + var value = reader.ReadValue(options); + values.Add(value); + } + + return new SqlRow(values); + } + + throw new JsonException($"Unexpected JSON token when deserializing {nameof(SqlRow)}."); + } + + public override void Write(Utf8JsonWriter writer, SqlRow value, JsonSerializerOptions options) => throw new NotImplementedException(); +} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlValue.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlValue.cs index 2c6d0801646..ad7b333e051 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlValue.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlValue.cs @@ -2,14 +2,11 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. -using System; -using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Sql; -[JsonConverter(typeof(SqlValueConverter))] +[JsonConverter(typeof(Json.SqlValueConverter))] public readonly struct SqlValue { private readonly LazyJson _lazyDocument; @@ -18,20 +15,3 @@ public readonly struct SqlValue public T? As() => _lazyDocument.As(); } - -internal sealed class SqlValueConverter : JsonConverter -{ - public override SqlValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Null) - { - reader.Read(); - return default; - } - - var lazyDoc = reader.ReadValue(options); - return new SqlValue(lazyDoc); - } - - public override void Write(Utf8JsonWriter writer, SqlValue value, JsonSerializerOptions options) => throw new NotImplementedException(); -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlValueConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlValueConverter.cs new file mode 100644 index 00000000000..c10486f782f --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Types/Sql/SqlValueConverter.cs @@ -0,0 +1,28 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Elastic.Clients.Elasticsearch.Sql.Json; + +public sealed class SqlValueConverter : JsonConverter +{ + public override SqlValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + { + reader.Read(); + return default; + } + + var lazyDoc = reader.ReadValue(options); + return new SqlValue(lazyDoc); + } + + public override void Write(Utf8JsonWriter writer, SqlValue value, JsonSerializerOptions options) => throw new NotImplementedException(); +} diff --git a/src/Playground/Person.cs b/src/Playground/Person.cs index e1fcf7bcffe..18bc62f1158 100644 --- a/src/Playground/Person.cs +++ b/src/Playground/Person.cs @@ -4,44 +4,44 @@ using System.Runtime.Serialization; using System.Text.Json.Serialization; + using Elastic.Clients.Elasticsearch; -using Playground; +using Elastic.Clients.Elasticsearch.Serialization; + +namespace Playground; + +[JsonSerializable(typeof(Person))] +internal partial class PlaygroundJsonSerializerContext : JsonSerializerContext; -namespace Playground +public class Person { - [JsonSerializable(typeof(Person))] - internal partial class PlaygroundJsonSerializerContext : JsonSerializerContext; - - public class Person - { - public int Id { get; set; } - - [JsonPropertyName("id2")] - public Guid SecondaryId { get; set; } = Guid.NewGuid(); - public string? FirstName { get; init; } - public string? LastName { get; init; } - public int? Age { get; init; } - public bool IsDeleted { get; init; } - public Routing? Routing { get; init; } - - public Id Idv3 => "testing"; - //public Guid Routing { get; init; } = Guid.NewGuid(); - - [JsonIgnore] - public string? Email { get; init; } - - [DataMember(Name = "STEVE")] - [IgnoreDataMember] - public string Data { get; init; } = "NOTHING"; - - public DateTimeKind Enum { get; init; } - } - - public class PersonV3 - { - public Guid SecondaryId { get; set; } = Guid.NewGuid(); - } -} + public int Id { get; set; } + + [JsonPropertyName("id2")] + public Guid SecondaryId { get; set; } = Guid.NewGuid(); + + public string? FirstName { get; init; } + public string? LastName { get; init; } + public int? Age { get; init; } + public bool IsDeleted { get; init; } + [JsonConverter(typeof(RequestResponseConverter))] + public Routing? Routing { get; init; } + [JsonConverter(typeof(RequestResponseConverter))] + public Id Idv3 => "testing"; + [JsonIgnore] + public string? Email { get; init; } + + [DataMember(Name = "STEVE")] + [IgnoreDataMember] + public string Data { get; init; } = "NOTHING"; + + public DateTimeKind Enum { get; init; } +} + +public class PersonV3 +{ + public Guid SecondaryId { get; set; } = Guid.NewGuid(); +} diff --git a/src/Playground/Program.cs b/src/Playground/Program.cs index 402bd448a62..805d1ff45e6 100644 --- a/src/Playground/Program.cs +++ b/src/Playground/Program.cs @@ -3,11 +3,12 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization.Metadata; + using Elastic.Clients.Elasticsearch; using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; using Elastic.Transport.Extensions; + using Playground; var pool = new SingleNodePool(new Uri("https://primary.es.europe-west3.gcp.cloud.es.io"));