diff --git a/src/Elastic.Clients.Elasticsearch/Types/Mapping/Properties.cs b/src/Elastic.Clients.Elasticsearch/Types/Mapping/Properties.cs index 1df10732432..1a082ad1659 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Mapping/Properties.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Mapping/Properties.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Linq.Expressions; namespace Elastic.Clients.Elasticsearch.Mapping; @@ -34,40 +33,3 @@ public partial class Properties : Properties { public void Add(Expression> name, IProperty property) => BackingDictionary.Add(name, property); } - -// TODO -// Code generator should generate these for any InternallyTaggedUnions that are IsADictionary types. -// These work on generic and non-generic descriptors. -//public partial class TypeMappingDescriptor -//{ -// public TypeMappingDescriptor Properties(PropertiesDescriptor descriptor) -// { -// PropertiesValue = descriptor.PromisedValue; -// return Self; -// } - -// public TypeMappingDescriptor Properties(Action> configure) -// { -// var descriptor = new PropertiesDescriptor(); -// configure?.Invoke(descriptor); -// PropertiesValue = descriptor.PromisedValue; -// return Self; -// } -//} - -//public partial class TypeMappingDescriptor -//{ -// public TypeMappingDescriptor Properties(PropertiesDescriptor descriptor) -// { -// PropertiesValue = descriptor.PromisedValue; -// return Self; -// } - -// public TypeMappingDescriptor Properties(Action> configure) -// { -// var descriptor = new PropertiesDescriptor(); -// configure?.Invoke(descriptor); -// PropertiesValue = descriptor.PromisedValue; -// return Self; -// } -//} diff --git a/src/Elastic.Clients.Elasticsearch/Types/Mapping/PropertyBase.cs b/src/Elastic.Clients.Elasticsearch/Types/Mapping/PropertyBase.cs deleted file mode 100644 index 4250fa12c69..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Types/Mapping/PropertyBase.cs +++ /dev/null @@ -1,55 +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.Mapping; - -[JsonConverter(typeof(PropertyInterfaceConverter))] -public partial interface IProperty -{ -} - -internal sealed partial class PropertyInterfaceConverter : JsonConverter -{ - public override IProperty? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var copiedReader = reader; - - string? type = null; - - using var jsonDoc = JsonDocument.ParseValue(ref copiedReader); - - if (jsonDoc is not null) - { - var root = jsonDoc.RootElement; - - if (root.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String) - { - type = readType.ToString(); - } - } - - // object is the default when no type is specified in the property object - if (type is null) - return JsonSerializer.Deserialize(ref reader, options); - - return DeserializeVariant(type, ref reader, options); - } - - public override void Write(Utf8JsonWriter writer, IProperty value, JsonSerializerOptions options) - { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - var type = value.GetType(); - - JsonSerializer.Serialize(writer, value, type, options); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Aggregations/AggregateDictionary.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Aggregations/AggregateDictionary.g.cs index 2f52a28c97d..3da8891bdba 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Aggregations/AggregateDictionary.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Aggregations/AggregateDictionary.g.cs @@ -82,4 +82,4 @@ public AggregateDictionary(IReadOnlyDictionary backingDictio public Elastic.Clients.Elasticsearch.Aggregations.MatrixStatsAggregate? GetMatrixStats(string key) => TryGet(key); private TAggregate TryGet(string key) where TAggregate : class, IAggregate => BackingDictionary.TryGetValue(key, out var agg) ? agg as TAggregate : null; -} +} \ No newline at end of file diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Analyzers.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Analyzers.g.cs index 6cbc36978c2..5df25c3c387 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Analyzers.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Analyzers.g.cs @@ -93,10 +93,18 @@ public AnalyzersDescriptor() : base(new Analyzers()) public AnalyzersDescriptor Whitespace(string analyzerName, WhitespaceAnalyzer whitespaceAnalyzer) => AssignVariant(analyzerName, whitespaceAnalyzer); } -internal sealed partial class AnalyzerInterfaceConverter +internal sealed partial class AnalyzerInterfaceConverter : JsonConverter { - private static IAnalyzer DeserializeVariant(string type, ref Utf8JsonReader reader, JsonSerializerOptions options) + public override IAnalyzer Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var copiedReader = reader; + string? type = null; + using var jsonDoc = JsonDocument.ParseValue(ref copiedReader); + if (jsonDoc is not null && jsonDoc.RootElement.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String) + { + type = readType.ToString(); + } + switch (type) { case "dutch": @@ -131,8 +139,68 @@ private static IAnalyzer DeserializeVariant(string type, ref Utf8JsonReader read throw new JsonException("Encounted an unknown variant type which could not be deserialised."); } } + + public override void Write(Utf8JsonWriter writer, IAnalyzer value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + switch (value.Type) + { + case "dutch": + JsonSerializer.Serialize(writer, value, typeof(DutchAnalyzer), options); + return; + case "snowball": + JsonSerializer.Serialize(writer, value, typeof(SnowballAnalyzer), options); + return; + case "kuromoji": + JsonSerializer.Serialize(writer, value, typeof(KuromojiAnalyzer), options); + return; + case "icu_analyzer": + JsonSerializer.Serialize(writer, value, typeof(IcuAnalyzer), options); + return; + case "whitespace": + JsonSerializer.Serialize(writer, value, typeof(WhitespaceAnalyzer), options); + return; + case "stop": + JsonSerializer.Serialize(writer, value, typeof(StopAnalyzer), options); + return; + case "standard": + JsonSerializer.Serialize(writer, value, typeof(StandardAnalyzer), options); + return; + case "simple": + JsonSerializer.Serialize(writer, value, typeof(SimpleAnalyzer), options); + return; + case "pattern": + JsonSerializer.Serialize(writer, value, typeof(PatternAnalyzer), options); + return; + case "nori": + JsonSerializer.Serialize(writer, value, typeof(NoriAnalyzer), options); + return; + case "language": + JsonSerializer.Serialize(writer, value, typeof(LanguageAnalyzer), options); + return; + case "keyword": + JsonSerializer.Serialize(writer, value, typeof(KeywordAnalyzer), options); + return; + case "fingerprint": + JsonSerializer.Serialize(writer, value, typeof(FingerprintAnalyzer), options); + return; + case "custom": + JsonSerializer.Serialize(writer, value, typeof(CustomAnalyzer), options); + return; + default: + var type = value.GetType(); + JsonSerializer.Serialize(writer, value, type, options); + return; + } + } } +[JsonConverter(typeof(AnalyzerInterfaceConverter))] public partial interface IAnalyzer { public string Type { get; } diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/CharFilterDefinitions.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/CharFilterDefinitions.g.cs index ca321aec350..42f5f82a0dc 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/CharFilterDefinitions.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/CharFilterDefinitions.g.cs @@ -66,10 +66,18 @@ public CharFilterDefinitionsDescriptor() : base(new CharFilterDefinitions()) public CharFilterDefinitionsDescriptor PatternReplaceCharFilter(string charFilterDefinitionName, PatternReplaceCharFilter patternReplaceCharFilter) => AssignVariant(charFilterDefinitionName, patternReplaceCharFilter); } -internal sealed partial class CharFilterDefinitionInterfaceConverter +internal sealed partial class CharFilterDefinitionInterfaceConverter : JsonConverter { - private static ICharFilterDefinition DeserializeVariant(string type, ref Utf8JsonReader reader, JsonSerializerOptions options) + public override ICharFilterDefinition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var copiedReader = reader; + string? type = null; + using var jsonDoc = JsonDocument.ParseValue(ref copiedReader); + if (jsonDoc is not null && jsonDoc.RootElement.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String) + { + type = readType.ToString(); + } + switch (type) { case "kuromoji_iteration_mark": @@ -86,8 +94,41 @@ private static ICharFilterDefinition DeserializeVariant(string type, ref Utf8Jso throw new JsonException("Encounted an unknown variant type which could not be deserialised."); } } + + public override void Write(Utf8JsonWriter writer, ICharFilterDefinition value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + switch (value.Type) + { + case "kuromoji_iteration_mark": + JsonSerializer.Serialize(writer, value, typeof(KuromojiIterationMarkCharFilter), options); + return; + case "icu_normalizer": + JsonSerializer.Serialize(writer, value, typeof(IcuNormalizationCharFilter), options); + return; + case "pattern_replace": + JsonSerializer.Serialize(writer, value, typeof(PatternReplaceCharFilter), options); + return; + case "mapping": + JsonSerializer.Serialize(writer, value, typeof(MappingCharFilter), options); + return; + case "html_strip": + JsonSerializer.Serialize(writer, value, typeof(HtmlStripCharFilter), options); + return; + default: + var type = value.GetType(); + JsonSerializer.Serialize(writer, value, type, options); + return; + } + } } +[JsonConverter(typeof(CharFilterDefinitionInterfaceConverter))] public partial interface ICharFilterDefinition { public string Type { get; } diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Normalizers.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Normalizers.g.cs index a6fb502645b..ebed634980b 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Normalizers.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/Normalizers.g.cs @@ -57,10 +57,18 @@ public NormalizersDescriptor() : base(new Normalizers()) public NormalizersDescriptor Lowercase(string normalizerName, LowercaseNormalizer lowercaseNormalizer) => AssignVariant(normalizerName, lowercaseNormalizer); } -internal sealed partial class NormalizerInterfaceConverter +internal sealed partial class NormalizerInterfaceConverter : JsonConverter { - private static INormalizer DeserializeVariant(string type, ref Utf8JsonReader reader, JsonSerializerOptions options) + public override INormalizer Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var copiedReader = reader; + string? type = null; + using var jsonDoc = JsonDocument.ParseValue(ref copiedReader); + if (jsonDoc is not null && jsonDoc.RootElement.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String) + { + type = readType.ToString(); + } + switch (type) { case "custom": @@ -71,8 +79,32 @@ private static INormalizer DeserializeVariant(string type, ref Utf8JsonReader re throw new JsonException("Encounted an unknown variant type which could not be deserialised."); } } + + public override void Write(Utf8JsonWriter writer, INormalizer value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + switch (value.Type) + { + case "custom": + JsonSerializer.Serialize(writer, value, typeof(CustomNormalizer), options); + return; + case "lowercase": + JsonSerializer.Serialize(writer, value, typeof(LowercaseNormalizer), options); + return; + default: + var type = value.GetType(); + JsonSerializer.Serialize(writer, value, type, options); + return; + } + } } +[JsonConverter(typeof(NormalizerInterfaceConverter))] public partial interface INormalizer { public string Type { get; } diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenFilterDefinitions.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenFilterDefinitions.g.cs index c6446bd011b..cf9fd5cf43d 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenFilterDefinitions.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenFilterDefinitions.g.cs @@ -195,10 +195,18 @@ public TokenFilterDefinitionsDescriptor() : base(new TokenFilterDefinitions()) public TokenFilterDefinitionsDescriptor WordDelimiterTokenFilter(string tokenFilterDefinitionName, WordDelimiterTokenFilter wordDelimiterTokenFilter) => AssignVariant(tokenFilterDefinitionName, wordDelimiterTokenFilter); } -internal sealed partial class TokenFilterDefinitionInterfaceConverter +internal sealed partial class TokenFilterDefinitionInterfaceConverter : JsonConverter { - private static ITokenFilterDefinition DeserializeVariant(string type, ref Utf8JsonReader reader, JsonSerializerOptions options) + public override ITokenFilterDefinition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var copiedReader = reader; + string? type = null; + using var jsonDoc = JsonDocument.ParseValue(ref copiedReader); + if (jsonDoc is not null && jsonDoc.RootElement.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String) + { + type = readType.ToString(); + } + switch (type) { case "dictionary_decompounder": @@ -301,8 +309,170 @@ private static ITokenFilterDefinition DeserializeVariant(string type, ref Utf8Js throw new JsonException("Encounted an unknown variant type which could not be deserialised."); } } + + public override void Write(Utf8JsonWriter writer, ITokenFilterDefinition value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + switch (value.Type) + { + case "dictionary_decompounder": + JsonSerializer.Serialize(writer, value, typeof(DictionaryDecompounderTokenFilter), options); + return; + case "phonetic": + JsonSerializer.Serialize(writer, value, typeof(PhoneticTokenFilter), options); + return; + case "icu_transform": + JsonSerializer.Serialize(writer, value, typeof(IcuTransformTokenFilter), options); + return; + case "icu_normalizer": + JsonSerializer.Serialize(writer, value, typeof(IcuNormalizationTokenFilter), options); + return; + case "icu_folding": + JsonSerializer.Serialize(writer, value, typeof(IcuFoldingTokenFilter), options); + return; + case "icu_collation": + JsonSerializer.Serialize(writer, value, typeof(IcuCollationTokenFilter), options); + return; + case "icu_tokenizer": + JsonSerializer.Serialize(writer, value, typeof(IcuTokenizer), options); + return; + case "kuromoji_part_of_speech": + JsonSerializer.Serialize(writer, value, typeof(KuromojiPartOfSpeechTokenFilter), options); + return; + case "kuromoji_readingform": + JsonSerializer.Serialize(writer, value, typeof(KuromojiReadingFormTokenFilter), options); + return; + case "kuromoji_stemmer": + JsonSerializer.Serialize(writer, value, typeof(KuromojiStemmerTokenFilter), options); + return; + case "word_delimiter": + JsonSerializer.Serialize(writer, value, typeof(WordDelimiterTokenFilter), options); + return; + case "word_delimiter_graph": + JsonSerializer.Serialize(writer, value, typeof(WordDelimiterGraphTokenFilter), options); + return; + case "uppercase": + JsonSerializer.Serialize(writer, value, typeof(UppercaseTokenFilter), options); + return; + case "unique": + JsonSerializer.Serialize(writer, value, typeof(UniqueTokenFilter), options); + return; + case "truncate": + JsonSerializer.Serialize(writer, value, typeof(TruncateTokenFilter), options); + return; + case "trim": + JsonSerializer.Serialize(writer, value, typeof(TrimTokenFilter), options); + return; + case "synonym": + JsonSerializer.Serialize(writer, value, typeof(SynonymTokenFilter), options); + return; + case "synonym_graph": + JsonSerializer.Serialize(writer, value, typeof(SynonymGraphTokenFilter), options); + return; + case "stop": + JsonSerializer.Serialize(writer, value, typeof(StopTokenFilter), options); + return; + case "stemmer": + JsonSerializer.Serialize(writer, value, typeof(StemmerTokenFilter), options); + return; + case "stemmer_override": + JsonSerializer.Serialize(writer, value, typeof(StemmerOverrideTokenFilter), options); + return; + case "snowball": + JsonSerializer.Serialize(writer, value, typeof(SnowballTokenFilter), options); + return; + case "shingle": + JsonSerializer.Serialize(writer, value, typeof(ShingleTokenFilter), options); + return; + case "reverse": + JsonSerializer.Serialize(writer, value, typeof(ReverseTokenFilter), options); + return; + case "remove_duplicates": + JsonSerializer.Serialize(writer, value, typeof(RemoveDuplicatesTokenFilter), options); + return; + case "predicate_token_filter": + JsonSerializer.Serialize(writer, value, typeof(PredicateTokenFilter), options); + return; + case "porter_stem": + JsonSerializer.Serialize(writer, value, typeof(PorterStemTokenFilter), options); + return; + case "pattern_replace": + JsonSerializer.Serialize(writer, value, typeof(PatternReplaceTokenFilter), options); + return; + case "pattern_capture": + JsonSerializer.Serialize(writer, value, typeof(PatternCaptureTokenFilter), options); + return; + case "nori_part_of_speech": + JsonSerializer.Serialize(writer, value, typeof(NoriPartOfSpeechTokenFilter), options); + return; + case "ngram": + JsonSerializer.Serialize(writer, value, typeof(NGramTokenFilter), options); + return; + case "multiplexer": + JsonSerializer.Serialize(writer, value, typeof(MultiplexerTokenFilter), options); + return; + case "lowercase": + JsonSerializer.Serialize(writer, value, typeof(LowercaseTokenFilter), options); + return; + case "limit": + JsonSerializer.Serialize(writer, value, typeof(LimitTokenCountTokenFilter), options); + return; + case "length": + JsonSerializer.Serialize(writer, value, typeof(LengthTokenFilter), options); + return; + case "kstem": + JsonSerializer.Serialize(writer, value, typeof(KStemTokenFilter), options); + return; + case "keyword_marker": + JsonSerializer.Serialize(writer, value, typeof(KeywordMarkerTokenFilter), options); + return; + case "keep": + JsonSerializer.Serialize(writer, value, typeof(KeepWordsTokenFilter), options); + return; + case "keep_types": + JsonSerializer.Serialize(writer, value, typeof(KeepTypesTokenFilter), options); + return; + case "hyphenation_decompounder": + JsonSerializer.Serialize(writer, value, typeof(HyphenationDecompounderTokenFilter), options); + return; + case "hunspell": + JsonSerializer.Serialize(writer, value, typeof(HunspellTokenFilter), options); + return; + case "fingerprint": + JsonSerializer.Serialize(writer, value, typeof(FingerprintTokenFilter), options); + return; + case "elision": + JsonSerializer.Serialize(writer, value, typeof(ElisionTokenFilter), options); + return; + case "edge_ngram": + JsonSerializer.Serialize(writer, value, typeof(EdgeNGramTokenFilter), options); + return; + case "delimited_payload": + JsonSerializer.Serialize(writer, value, typeof(DelimitedPayloadTokenFilter), options); + return; + case "condition": + JsonSerializer.Serialize(writer, value, typeof(ConditionTokenFilter), options); + return; + case "common_grams": + JsonSerializer.Serialize(writer, value, typeof(CommonGramsTokenFilter), options); + return; + case "asciifolding": + JsonSerializer.Serialize(writer, value, typeof(AsciiFoldingTokenFilter), options); + return; + default: + var type = value.GetType(); + JsonSerializer.Serialize(writer, value, type, options); + return; + } + } } +[JsonConverter(typeof(TokenFilterDefinitionInterfaceConverter))] public partial interface ITokenFilterDefinition { public string Type { get; } diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenizerDefinitions.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenizerDefinitions.g.cs index b960fe910be..8ca703f5f4a 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenizerDefinitions.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Analysis/TokenizerDefinitions.g.cs @@ -93,10 +93,18 @@ public TokenizerDefinitionsDescriptor() : base(new TokenizerDefinitions()) public TokenizerDefinitionsDescriptor WhitespaceTokenizer(string tokenizerDefinitionName, WhitespaceTokenizer whitespaceTokenizer) => AssignVariant(tokenizerDefinitionName, whitespaceTokenizer); } -internal sealed partial class TokenizerDefinitionInterfaceConverter +internal sealed partial class TokenizerDefinitionInterfaceConverter : JsonConverter { - private static ITokenizerDefinition DeserializeVariant(string type, ref Utf8JsonReader reader, JsonSerializerOptions options) + public override ITokenizerDefinition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var copiedReader = reader; + string? type = null; + using var jsonDoc = JsonDocument.ParseValue(ref copiedReader); + if (jsonDoc is not null && jsonDoc.RootElement.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String) + { + type = readType.ToString(); + } + switch (type) { case "icu_tokenizer": @@ -131,8 +139,68 @@ private static ITokenizerDefinition DeserializeVariant(string type, ref Utf8Json throw new JsonException("Encounted an unknown variant type which could not be deserialised."); } } + + public override void Write(Utf8JsonWriter writer, ITokenizerDefinition value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + switch (value.Type) + { + case "icu_tokenizer": + JsonSerializer.Serialize(writer, value, typeof(IcuTokenizer), options); + return; + case "pattern": + JsonSerializer.Serialize(writer, value, typeof(PatternTokenizer), options); + return; + case "kuromoji_tokenizer": + JsonSerializer.Serialize(writer, value, typeof(KuromojiTokenizer), options); + return; + case "whitespace": + JsonSerializer.Serialize(writer, value, typeof(WhitespaceTokenizer), options); + return; + case "uax_url_email": + JsonSerializer.Serialize(writer, value, typeof(UaxEmailUrlTokenizer), options); + return; + case "standard": + JsonSerializer.Serialize(writer, value, typeof(StandardTokenizer), options); + return; + case "path_hierarchy": + JsonSerializer.Serialize(writer, value, typeof(PathHierarchyTokenizer), options); + return; + case "nori_tokenizer": + JsonSerializer.Serialize(writer, value, typeof(NoriTokenizer), options); + return; + case "ngram": + JsonSerializer.Serialize(writer, value, typeof(NGramTokenizer), options); + return; + case "lowercase": + JsonSerializer.Serialize(writer, value, typeof(LowercaseTokenizer), options); + return; + case "letter": + JsonSerializer.Serialize(writer, value, typeof(LetterTokenizer), options); + return; + case "keyword": + JsonSerializer.Serialize(writer, value, typeof(KeywordTokenizer), options); + return; + case "edge_ngram": + JsonSerializer.Serialize(writer, value, typeof(EdgeNGramTokenizer), options); + return; + case "char_group": + JsonSerializer.Serialize(writer, value, typeof(CharGroupTokenizer), options); + return; + default: + var type = value.GetType(); + JsonSerializer.Serialize(writer, value, type, options); + return; + } + } } +[JsonConverter(typeof(TokenizerDefinitionInterfaceConverter))] public partial interface ITokenizerDefinition { public string Type { get; } diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Mapping/Properties.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Mapping/Properties.g.cs index fbe714a403e..9417bd89b05 100644 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/Mapping/Properties.g.cs +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/Mapping/Properties.g.cs @@ -281,10 +281,18 @@ public PropertiesDescriptor() : base(new Properties()) public PropertiesDescriptor Wildcard(Expression> propertyName, Action> configure) => AssignVariant, WildcardProperty>(propertyName, configure); } -internal sealed partial class PropertyInterfaceConverter +internal sealed partial class PropertyInterfaceConverter : JsonConverter { - private static IProperty DeserializeVariant(string type, ref Utf8JsonReader reader, JsonSerializerOptions options) + public override IProperty Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var copiedReader = reader; + string? type = null; + using var jsonDoc = JsonDocument.ParseValue(ref copiedReader); + if (jsonDoc is not null && jsonDoc.RootElement.TryGetProperty("type", out var readType) && readType.ValueKind == JsonValueKind.String) + { + type = readType.ToString(); + } + switch (type) { case "long_range": @@ -383,8 +391,164 @@ private static IProperty DeserializeVariant(string type, ref Utf8JsonReader read throw new JsonException("Encounted an unknown variant type which could not be deserialised."); } } + + public override void Write(Utf8JsonWriter writer, IProperty value, JsonSerializerOptions options) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + switch (value.Type) + { + case "long_range": + JsonSerializer.Serialize(writer, value, typeof(LongRangeProperty), options); + return; + case "ip_range": + JsonSerializer.Serialize(writer, value, typeof(IpRangeProperty), options); + return; + case "integer_range": + JsonSerializer.Serialize(writer, value, typeof(IntegerRangeProperty), options); + return; + case "float_range": + JsonSerializer.Serialize(writer, value, typeof(FloatRangeProperty), options); + return; + case "double_range": + JsonSerializer.Serialize(writer, value, typeof(DoubleRangeProperty), options); + return; + case "date_range": + JsonSerializer.Serialize(writer, value, typeof(DateRangeProperty), options); + return; + case "unsigned_long": + JsonSerializer.Serialize(writer, value, typeof(UnsignedLongNumberProperty), options); + return; + case "short": + JsonSerializer.Serialize(writer, value, typeof(ShortNumberProperty), options); + return; + case "scaled_float": + JsonSerializer.Serialize(writer, value, typeof(ScaledFloatNumberProperty), options); + return; + case "long": + JsonSerializer.Serialize(writer, value, typeof(LongNumberProperty), options); + return; + case "integer": + JsonSerializer.Serialize(writer, value, typeof(IntegerNumberProperty), options); + return; + case "half_float": + JsonSerializer.Serialize(writer, value, typeof(HalfFloatNumberProperty), options); + return; + case "float": + JsonSerializer.Serialize(writer, value, typeof(FloatNumberProperty), options); + return; + case "double": + JsonSerializer.Serialize(writer, value, typeof(DoubleNumberProperty), options); + return; + case "byte": + JsonSerializer.Serialize(writer, value, typeof(ByteNumberProperty), options); + return; + case "shape": + JsonSerializer.Serialize(writer, value, typeof(ShapeProperty), options); + return; + case "point": + JsonSerializer.Serialize(writer, value, typeof(PointProperty), options); + return; + case "geo_shape": + JsonSerializer.Serialize(writer, value, typeof(GeoShapeProperty), options); + return; + case "geo_point": + JsonSerializer.Serialize(writer, value, typeof(GeoPointProperty), options); + return; + case "token_count": + JsonSerializer.Serialize(writer, value, typeof(TokenCountProperty), options); + return; + case "murmur3": + JsonSerializer.Serialize(writer, value, typeof(Murmur3HashProperty), options); + return; + case "ip": + JsonSerializer.Serialize(writer, value, typeof(IpProperty), options); + return; + case "histogram": + JsonSerializer.Serialize(writer, value, typeof(HistogramProperty), options); + return; + case "alias": + JsonSerializer.Serialize(writer, value, typeof(FieldAliasProperty), options); + return; + case "constant_keyword": + JsonSerializer.Serialize(writer, value, typeof(ConstantKeywordProperty), options); + return; + case "completion": + JsonSerializer.Serialize(writer, value, typeof(CompletionProperty), options); + return; + case "object": + JsonSerializer.Serialize(writer, value, typeof(ObjectProperty), options); + return; + case "nested": + JsonSerializer.Serialize(writer, value, typeof(NestedProperty), options); + return; + case "flattened": + JsonSerializer.Serialize(writer, value, typeof(FlattenedProperty), options); + return; + case "dense_vector": + JsonSerializer.Serialize(writer, value, typeof(DenseVectorProperty), options); + return; + case "aggregate_metric_double": + JsonSerializer.Serialize(writer, value, typeof(AggregateMetricDoubleProperty), options); + return; + case "date": + JsonSerializer.Serialize(writer, value, typeof(DateProperty), options); + return; + case "date_nanos": + JsonSerializer.Serialize(writer, value, typeof(DateNanosProperty), options); + return; + case "wildcard": + JsonSerializer.Serialize(writer, value, typeof(WildcardProperty), options); + return; + case "version": + JsonSerializer.Serialize(writer, value, typeof(VersionProperty), options); + return; + case "text": + JsonSerializer.Serialize(writer, value, typeof(TextProperty), options); + return; + case "search_as_you_type": + JsonSerializer.Serialize(writer, value, typeof(SearchAsYouTypeProperty), options); + return; + case "rank_features": + JsonSerializer.Serialize(writer, value, typeof(RankFeaturesProperty), options); + return; + case "rank_feature": + JsonSerializer.Serialize(writer, value, typeof(RankFeatureProperty), options); + return; + case "percolator": + JsonSerializer.Serialize(writer, value, typeof(PercolatorProperty), options); + return; + case "match_only_text": + JsonSerializer.Serialize(writer, value, typeof(MatchOnlyTextProperty), options); + return; + case "keyword": + JsonSerializer.Serialize(writer, value, typeof(KeywordProperty), options); + return; + case "join": + JsonSerializer.Serialize(writer, value, typeof(JoinProperty), options); + return; + case "{dynamic_property}": + JsonSerializer.Serialize(writer, value, typeof(DynamicProperty), options); + return; + case "boolean": + JsonSerializer.Serialize(writer, value, typeof(BooleanProperty), options); + return; + case "binary": + JsonSerializer.Serialize(writer, value, typeof(BinaryProperty), options); + return; + default: + var type = value.GetType(); + JsonSerializer.Serialize(writer, value, type, options); + return; + } + } } +[JsonConverter(typeof(PropertyInterfaceConverter))] public partial interface IProperty { public string Type { get; } diff --git a/tests/Tests/IndexManagement/IndexSettingsSerializationTests.cs b/tests/Tests/IndexManagement/IndexSettingsSerializationTests.cs new file mode 100644 index 00000000000..c70c33cd841 --- /dev/null +++ b/tests/Tests/IndexManagement/IndexSettingsSerializationTests.cs @@ -0,0 +1,74 @@ +// 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.Linq; +using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Analysis; +using Elastic.Clients.Elasticsearch.IndexManagement; +using Tests.Domain; +using Tests.Serialization; +using VerifyXunit; +using Xunit.Sdk; + +namespace Tests.IndexManagement; + +[UsesVerify] +public class IndexSettingsSerializationTests : SerializerTestBase +{ + private const string IndexSettingsJson = @"{""creation_date"":""1655895084631""}"; + + [U] + public async Task CanSerializerIndexSettingsWithCustomAnalyzer() + { + // Test case for https://github.com/elastic/elasticsearch-net/issues/6739 + // Resolved after improved code-generation of internally-tagged untions to include + // converters for the variant interfaces. + + var descriptor = new IndexSettingsDescriptor(); + descriptor.Analysis(a => a + .Analyzer(a => a + .Custom("whitespace_lowercase", wl => wl + .Tokenizer("whitespace") + .Filter(Enumerable.Repeat("lowercase", 1)) + ) + ) + ); + + var json = SerializeAndGetJsonString(descriptor); + await Verifier.VerifyJson(json); + + var indexSettings = DeserializeJsonString(json); + var analyzer = indexSettings.Analysis.Analyzer["whitespace_lowercase"]; + var customAnalyzer = analyzer.Should().BeAssignableTo().Subject; + customAnalyzer.Tokenizer.Should().Be("whitespace"); + customAnalyzer.Filter.Should().ContainSingle("lowercase"); + + var objectJson = SerializeAndGetJsonString(indexSettings); + objectJson.Should().Be(json); + } + + [U] + public async Task CanSerialize_CreationDate() + { + var settings = new IndexSettings { CreationDate = 1655895084631 }; + var json = SerializeAndGetJsonString(settings); + await Verifier.VerifyJson(json); + } + + [U] + public async Task CanSerialize_NullCreationDate() + { + var settings = new IndexSettings(); + var json = SerializeAndGetJsonString(settings); + await Verifier.VerifyJson(json); + } + + [U] + public void CanDeserialize_StringifiedCreationDate() + { + var stream = WrapInStream(IndexSettingsJson); + var settings = _requestResponseSerializer.Deserialize(stream); + settings.CreationDate.Should().Be(1655895084631); + } +} diff --git a/tests/Tests/Serialization/Indices/IndexSettingsSerialisationTests.cs b/tests/Tests/Serialization/Indices/IndexSettingsSerialisationTests.cs deleted file mode 100644 index 474817e3e7c..00000000000 --- a/tests/Tests/Serialization/Indices/IndexSettingsSerialisationTests.cs +++ /dev/null @@ -1,39 +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.Threading.Tasks; -using Elastic.Clients.Elasticsearch.IndexManagement; -using VerifyXunit; - -namespace Tests.Serialization; - -[UsesVerify] -public class IndexSettingsSerializationTests : SerializerTestBase -{ - private const string IndexSettingsJson = @"{""creation_date"":""1655895084631""}"; - - [U] - public async Task CanSerialize_CreationDate() - { - var settings = new IndexSettings { CreationDate = 1655895084631 }; - var json = SerializeAndGetJsonString(settings); - await Verifier.VerifyJson(json); - } - - [U] - public async Task CanSerialize_NullCreationDate() - { - var settings = new IndexSettings(); - var json = SerializeAndGetJsonString(settings); - await Verifier.VerifyJson(json); - } - - [U] - public void CanDeserialize_StringifiedCreationDate() - { - var stream = WrapInStream(IndexSettingsJson); - var settings = _requestResponseSerializer.Deserialize(stream); - settings.CreationDate.Should().Be(1655895084631); - } -} diff --git a/tests/Tests/_VerifySnapshots/IndexSettingsSerializationTests.CanSerializerIndexSettingsWithCustomAnalyzer.verified.txt b/tests/Tests/_VerifySnapshots/IndexSettingsSerializationTests.CanSerializerIndexSettingsWithCustomAnalyzer.verified.txt new file mode 100644 index 00000000000..697f6e8a705 --- /dev/null +++ b/tests/Tests/_VerifySnapshots/IndexSettingsSerializationTests.CanSerializerIndexSettingsWithCustomAnalyzer.verified.txt @@ -0,0 +1,13 @@ +{ + analysis: { + analyzer: { + whitespace_lowercase: { + filter: [ + lowercase + ], + tokenizer: whitespace, + type: custom + } + } + } +} \ No newline at end of file