Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7b649db

Browse files
committedFeb 7, 2025··
Implement IParsable<T> for url parameters
1 parent 4e18b84 commit 7b649db

File tree

18 files changed

+633
-57
lines changed

18 files changed

+633
-57
lines changed
 

‎global.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
{
22
"sdk": {
3-
"version": "8.0.400",
3+
"version": "9.0.100",
44
"rollForward": "latestFeature",
55
"allowPrerelease": false
6-
},
7-
"version": "8.8.0-alpha.1",
8-
"doc_current": "main",
9-
"doc_branch": "main"
6+
}
107
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/DateTime/Duration.cs

+42-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections.Generic;
7+
using System.Diagnostics.CodeAnalysis;
68
using System.Globalization;
79
using System.Text.Json;
810
using System.Text.Json.Serialization;
@@ -15,7 +17,13 @@ namespace Elastic.Clients.Elasticsearch;
1517
/// Represents a duration value.
1618
/// </summary>
1719
[JsonConverter(typeof(DurationConverter))]
18-
public sealed class Duration : IComparable<Duration>, IEquatable<Duration>, IUrlParameter
20+
public sealed class Duration :
21+
IComparable<Duration>,
22+
IEquatable<Duration>,
23+
IUrlParameter
24+
#if NET7_0_OR_GREATER
25+
, IParsable<Duration>
26+
#endif
1927
{
2028
private const double MicrosecondsInATick = 0.1; // 10 ticks = 1 microsecond
2129
private const double MillisecondsInADay = MillisecondsInAnHour * 24;
@@ -390,6 +398,39 @@ private static string ExponentFormat(double d)
390398
var exponent = (int)((bits >> 52) & 0x7ffL);
391399
return new string('#', Math.Max(2, exponent));
392400
}
401+
402+
#region IParsable
403+
404+
#if NET7_0_OR_GREATER
405+
406+
public static Duration Parse(string s, IFormatProvider? provider) =>
407+
TryParse(s, provider, out var result) ? result : throw new FormatException();
408+
409+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
410+
[NotNullWhen(true)] out Duration? result)
411+
{
412+
if (s is null)
413+
{
414+
result = null;
415+
return false;
416+
}
417+
418+
try
419+
{
420+
result = new Duration(s);
421+
}
422+
catch
423+
{
424+
result = null;
425+
return false;
426+
}
427+
428+
return true;
429+
}
430+
431+
#endif
432+
433+
#endregion IParsable
393434
}
394435

395436
internal sealed class DurationConverter : JsonConverter<Duration>

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Fluent/Descriptor.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ public abstract class Descriptor<TDescriptor> : Descriptor
5858
protected TDescriptor Self => _self;
5959

6060
[MethodImpl(MethodImplOptions.AggressiveInlining)]
61-
protected TDescriptor Assign<TValue>(TValue value, Action<TDescriptor, TValue> assign) => FluentAssign.Assign(_self, value, assign);
61+
protected TDescriptor Assign<TValue>(TValue value, Action<TDescriptor, TValue> assign)
62+
{
63+
assign(_self, value);
64+
return _self;
65+
}
6266
}
6367

6468
public abstract class SerializableDescriptor<TDescriptor> : Descriptor<TDescriptor>, ISelfSerializable

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Fluent/Fluent.cs

-19
This file was deleted.

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Field/Field.cs

+27
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ namespace Elastic.Clients.Elasticsearch;
2424
public sealed class Field :
2525
IEquatable<Field>,
2626
IUrlParameter
27+
#if NET7_0_OR_GREATER
28+
, IParsable<Field>
29+
#endif
2730
{
2831
private readonly object _comparisonValue;
2932
private readonly Type? _type;
@@ -197,6 +200,30 @@ public override int GetHashCode()
197200

198201
#endregion Equality
199202

203+
#region IParsable
204+
205+
#if NET7_0_OR_GREATER
206+
207+
public static Field Parse(string s, IFormatProvider? provider) =>
208+
TryParse(s, provider, out var result) ? result : throw new FormatException();
209+
210+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
211+
[NotNullWhen(true)] out Field? result)
212+
{
213+
if (s is null)
214+
{
215+
result = null;
216+
return false;
217+
}
218+
219+
result = new Field(s);
220+
return true;
221+
}
222+
223+
#endif
224+
225+
#endregion IParsable
226+
200227
#region IUrlParameter
201228

202229
string IUrlParameter.GetString(ITransportConfiguration settings)

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Fields/Fields.cs

+46
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Collections;
77
using System.Collections.Generic;
88
using System.Diagnostics;
9+
using System.Diagnostics.CodeAnalysis;
910
using System.Linq;
1011
using System.Linq.Expressions;
1112
using System.Reflection;
@@ -19,6 +20,9 @@ public sealed class Fields :
1920
IEquatable<Fields>,
2021
IEnumerable<Field>,
2122
IUrlParameter
23+
#if NET7_0_OR_GREATER
24+
, IParsable<Fields>
25+
#endif
2226
{
2327
internal readonly List<Field> ListOfFields;
2428

@@ -183,6 +187,48 @@ public override bool Equals(object? obj) =>
183187

184188
#endregion IEnumerable
185189

190+
#region IParsable
191+
192+
#if NET7_0_OR_GREATER
193+
194+
public static Fields Parse(string s, IFormatProvider? provider) =>
195+
TryParse(s, provider, out var result) ? result : throw new FormatException();
196+
197+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
198+
[NotNullWhen(true)] out Fields? result)
199+
{
200+
if (s is null)
201+
{
202+
result = null;
203+
return false;
204+
}
205+
206+
if (s.IsNullOrEmptyCommaSeparatedList(out var list))
207+
{
208+
result = new Fields();
209+
return true;
210+
}
211+
212+
var fields = new List<Field>();
213+
foreach (var item in list)
214+
{
215+
if (!Field.TryParse(item, provider, out var field))
216+
{
217+
result = null;
218+
return false;
219+
}
220+
221+
fields.Add(field);
222+
}
223+
224+
result = new Fields(fields);
225+
return true;
226+
}
227+
228+
#endif
229+
230+
#endregion IParsable
231+
186232
#region IUrlParameter
187233

188234
string IUrlParameter.GetString(ITransportConfiguration? settings)

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Id.cs

+36-1
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,23 @@
44

55
using System;
66
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Globalization;
89
using System.Text.Json;
910
using System.Text.Json.Serialization;
11+
1012
using Elastic.Transport;
1113

1214
namespace Elastic.Clients.Elasticsearch;
1315

1416
[DebuggerDisplay("{DebugDisplay,nq}")]
1517
[JsonConverter(typeof(IdConverter))]
16-
public class Id : IEquatable<Id>, IUrlParameter
18+
public class Id :
19+
IEquatable<Id>,
20+
IUrlParameter
21+
#if NET7_0_OR_GREATER
22+
, IParsable<Id>
23+
#endif
1724
{
1825
public Id(string id)
1926
{
@@ -81,12 +88,16 @@ public override bool Equals(object obj)
8188
{
8289
case Id r:
8390
return Equals(r);
91+
8492
case string s:
8593
return Equals(s);
94+
8695
case int l:
8796
return Equals(l);
97+
8898
case long l:
8999
return Equals(l);
100+
90101
case Guid g:
91102
return Equals(g);
92103
}
@@ -108,4 +119,28 @@ public override int GetHashCode()
108119
public static bool operator ==(Id left, Id right) => Equals(left, right);
109120

110121
public static bool operator !=(Id left, Id right) => !Equals(left, right);
122+
123+
#region IParsable
124+
125+
#if NET7_0_OR_GREATER
126+
127+
public static Id Parse(string s, IFormatProvider? provider) =>
128+
TryParse(s, provider, out var result) ? result : throw new FormatException();
129+
130+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
131+
[NotNullWhen(true)] out Id? result)
132+
{
133+
if (s is null)
134+
{
135+
result = null;
136+
return false;
137+
}
138+
139+
result = new Id(s);
140+
return true;
141+
}
142+
143+
#endif
144+
145+
#endregion IParsable
111146
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Ids.cs

+56-2
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,42 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Diagnostics;
8+
using System.Diagnostics.CodeAnalysis;
89
using System.Linq;
910
using System.Text.Json.Serialization;
11+
1012
using Elastic.Transport;
1113

1214
namespace Elastic.Clients.Elasticsearch;
1315

1416
[DebuggerDisplay("{DebugDisplay,nq}")]
1517
[JsonConverter(typeof(IdsConverter))]
16-
public partial class Ids : IUrlParameter, IEquatable<Ids>
18+
public class Ids :
19+
IUrlParameter,
20+
IEquatable<Ids>
21+
#if NET7_0_OR_GREATER
22+
, IParsable<Ids>
23+
#endif
1724
{
1825
private readonly IList<Id> _ids;
1926

2027
public Ids(IEnumerable<Id> ids) => _ids = ids.ToList();
2128

2229
public Ids(IList<Id> ids) => _ids = ids;
2330

24-
public Ids(IEnumerable<string> ids) => _ids = ids.Select(i => new Id(i)).ToList();
31+
public Ids(IEnumerable<string> ids) => _ids = ids.Select(i => new Id(i)).ToList();
2532

2633
public Ids(string value)
2734
{
2835
if (!value.IsNullOrEmptyCommaSeparatedList(out var arr))
2936
_ids = arr.Select(i => new Id(i)).ToList();
3037
}
3138

39+
public Ids()
40+
{
41+
_ids = [];
42+
}
43+
3244
internal IList<Id> IdsToSerialize => _ids;
3345

3446
private string DebugDisplay => ((IUrlParameter)this).GetString(null);
@@ -82,4 +94,46 @@ public override int GetHashCode()
8294
public static bool operator ==(Ids left, Ids right) => Equals(left, right);
8395

8496
public static bool operator !=(Ids left, Ids right) => !Equals(left, right);
97+
98+
#region IParsable
99+
100+
#if NET7_0_OR_GREATER
101+
102+
public static Ids Parse(string s, IFormatProvider? provider) =>
103+
TryParse(s, provider, out var result) ? result : throw new FormatException();
104+
105+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
106+
[NotNullWhen(true)] out Ids? result)
107+
{
108+
if (s is null)
109+
{
110+
result = null;
111+
return false;
112+
}
113+
114+
if (s.IsNullOrEmptyCommaSeparatedList(out var list))
115+
{
116+
result = new Ids();
117+
return true;
118+
}
119+
120+
var ids = new List<Id>();
121+
foreach (var item in list)
122+
{
123+
if (!Id.TryParse(item, provider, out var id))
124+
{
125+
result = null;
126+
return false;
127+
}
128+
129+
ids.Add(id);
130+
}
131+
132+
result = new Ids(ids);
133+
return true;
134+
}
135+
136+
#endif
137+
138+
#endregion IParsable
85139
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/IndexName/IndexName.cs

+32-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
using System;
66
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Text.Json.Serialization;
9+
810
using Elastic.Transport;
911

1012
namespace Elastic.Clients.Elasticsearch;
@@ -14,7 +16,12 @@ namespace Elastic.Clients.Elasticsearch;
1416
/// </summary>
1517
[JsonConverter(typeof(IndexNameConverter))]
1618
[DebuggerDisplay("{DebugDisplay,nq}")]
17-
public class IndexName : IEquatable<IndexName>, IUrlParameter
19+
public class IndexName :
20+
IEquatable<IndexName>,
21+
IUrlParameter
22+
#if NET7_0_OR_GREATER
23+
, IParsable<IndexName>
24+
#endif
1825
{
1926
private const char ClusterSeparator = ':';
2027

@@ -134,4 +141,28 @@ private bool EqualsMarker(IndexName other)
134141

135142
return Type is not null && other?.Type is not null && Type == other.Type;
136143
}
144+
145+
#region IParsable
146+
147+
#if NET7_0_OR_GREATER
148+
149+
public static IndexName Parse(string s, IFormatProvider? provider) =>
150+
TryParse(s, provider, out var result) ? result : throw new FormatException();
151+
152+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
153+
[NotNullWhen(true)] out IndexName? result)
154+
{
155+
if (s is null)
156+
{
157+
result = null;
158+
return false;
159+
}
160+
161+
result = Parse(s);
162+
return true;
163+
}
164+
165+
#endif
166+
167+
#endregion IParsable
137168
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Indices/Indices.cs

+56-1
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,25 @@
66
using System.Collections;
77
using System.Collections.Generic;
88
using System.Diagnostics;
9+
using System.Diagnostics.CodeAnalysis;
910
using System.Linq;
1011
using System.Text.Json;
1112
using System.Text.Json.Serialization;
13+
1214
using Elastic.Clients.Elasticsearch.Serialization;
1315
using Elastic.Transport;
1416

1517
namespace Elastic.Clients.Elasticsearch;
1618

1719
[DebuggerDisplay("{DebugDisplay,nq}")]
1820
[JsonConverter(typeof(IndicesJsonConverter))]
19-
public sealed class Indices : IUrlParameter, IEnumerable<IndexName>, IEquatable<Indices>
21+
public sealed class Indices :
22+
IUrlParameter,
23+
IEnumerable<IndexName>,
24+
IEquatable<Indices>
25+
#if NET7_0_OR_GREATER
26+
, IParsable<Indices>
27+
#endif
2028
{
2129
private static readonly HashSet<IndexName> AllIndexList = new() { AllValue };
2230

@@ -26,6 +34,11 @@ public sealed class Indices : IUrlParameter, IEnumerable<IndexName>, IEquatable<
2634
private readonly HashSet<IndexName>? _indices;
2735
private readonly bool _isAllIndices;
2836

37+
internal Indices()
38+
{
39+
_indices = [];
40+
}
41+
2942
internal Indices(IndexName indexName)
3043
{
3144
if (indexName.Equals(AllValue) || indexName.Equals(WildcardValue))
@@ -188,6 +201,48 @@ public override int GetHashCode()
188201
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
189202

190203
public IEnumerator<IndexName> GetEnumerator() => IndexNames.GetEnumerator();
204+
205+
#region IParsable
206+
207+
#if NET7_0_OR_GREATER
208+
209+
public static Indices Parse(string s, IFormatProvider? provider) =>
210+
TryParse(s, provider, out var result) ? result : throw new FormatException();
211+
212+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
213+
[NotNullWhen(true)] out Indices? result)
214+
{
215+
if (s is null)
216+
{
217+
result = null;
218+
return false;
219+
}
220+
221+
if (s.IsNullOrEmptyCommaSeparatedList(out var list))
222+
{
223+
result = new Indices();
224+
return true;
225+
}
226+
227+
var names = new List<IndexName>();
228+
foreach (var item in list)
229+
{
230+
if (!IndexName.TryParse(item, provider, out var name))
231+
{
232+
result = null;
233+
return false;
234+
}
235+
236+
names.Add(name);
237+
}
238+
239+
result = new Indices(names);
240+
return true;
241+
}
242+
243+
#endif
244+
245+
#endregion IParsable
191246
}
192247

193248
internal sealed class IndicesJsonConverter : JsonConverter<Indices>

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/Routing.cs

+38-8
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,26 @@
44

55
using System;
66
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Globalization;
89
using System.Linq;
910
using System.Text.Json;
1011
using System.Text.Json.Serialization;
12+
1113
using Elastic.Transport;
1214

1315
namespace Elastic.Clients.Elasticsearch;
1416

1517
[JsonConverter(typeof(RoutingConverter))]
1618
[DebuggerDisplay("{" + nameof(DebugDisplay) + ",nq}")]
17-
public class Routing : IEquatable<Routing>, IUrlParameter
19+
public class Routing :
20+
IEquatable<Routing>,
21+
IUrlParameter
22+
#if NET7_0_OR_GREATER
23+
, IParsable<Routing>
24+
#endif
1825
{
19-
private static readonly char[] Separator = {','};
26+
private static readonly char[] Separator = { ',' };
2027

2128
internal Routing(Func<object> documentGetter)
2229
{
@@ -66,8 +73,10 @@ public bool Equals(Routing other)
6673
var t = DocumentGetter();
6774
var o = other.DocumentGetter();
6875
return t?.Equals(o) ?? false;
76+
6977
case 4:
7078
return Document?.Equals(other.Document) ?? false;
79+
7180
default:
7281
return StringEquals(StringOrLongValue, other.StringOrLongValue);
7382
}
@@ -141,12 +150,16 @@ public override bool Equals(object obj)
141150
{
142151
case Routing r:
143152
return Equals(r);
153+
144154
case string s:
145155
return Equals(s);
156+
146157
case int l:
147158
return Equals(l);
159+
148160
case long l:
149161
return Equals(l);
162+
150163
case Guid g:
151164
return Equals(g);
152165
}
@@ -167,10 +180,27 @@ public override int GetHashCode()
167180
}
168181
}
169182

170-
//internal bool ShouldSerialize(IJsonFormatterResolver formatterResolver)
171-
//{
172-
// var inferrer = formatterResolver.GetConnectionSettings().Inferrer;
173-
// var resolved = inferrer.Resolve(this);
174-
// return !resolved.IsNullOrEmpty();
175-
//}
183+
#region IParsable
184+
185+
#if NET7_0_OR_GREATER
186+
187+
public static Routing Parse(string s, IFormatProvider? provider) =>
188+
TryParse(s, provider, out var result) ? result : throw new FormatException();
189+
190+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
191+
[NotNullWhen(true)] out Routing? result)
192+
{
193+
if (s is null)
194+
{
195+
result = null;
196+
return false;
197+
}
198+
199+
result = new Routing(s);
200+
return true;
201+
}
202+
203+
#endif
204+
205+
#endregion IParsable
176206
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamName.cs

+32-1
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44

55
using System;
66
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Text.Json;
89
using System.Text.Json.Serialization;
10+
911
using Elastic.Transport;
1012

1113
namespace Elastic.Clients.Elasticsearch;
1214

1315
[JsonConverter(typeof(DataStreamNameConverter))]
1416
[DebuggerDisplay("{DebugDisplay,nq}")]
15-
public sealed class DataStreamName : IEquatable<DataStreamName>, IUrlParameter
17+
public sealed class DataStreamName :
18+
IEquatable<DataStreamName>,
19+
IUrlParameter
20+
#if NET7_0_OR_GREATER
21+
, IParsable<DataStreamName>
22+
#endif
1623
{
1724
internal DataStreamName(string dataStreamName) => Name = dataStreamName;
1825

@@ -53,6 +60,30 @@ public override int GetHashCode()
5360
return (TypeHashCode * 23) ^ (Name.GetHashCode());
5461
}
5562
}
63+
64+
#region IParsable
65+
66+
#if NET7_0_OR_GREATER
67+
68+
public static DataStreamName Parse(string s, IFormatProvider? provider) =>
69+
TryParse(s, provider, out var result) ? result : throw new FormatException();
70+
71+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
72+
[NotNullWhen(true)] out DataStreamName? result)
73+
{
74+
if (s is null)
75+
{
76+
result = null;
77+
return false;
78+
}
79+
80+
result = new DataStreamName(s);
81+
return true;
82+
}
83+
84+
#endif
85+
86+
#endregion IParsable
5687
}
5788

5889
internal sealed class DataStreamNameConverter : JsonConverter<DataStreamName>

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/DataStreamNames/DataStreamNames.cs

+51-1
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,24 @@
66
using System.Collections;
77
using System.Collections.Generic;
88
using System.Diagnostics;
9+
using System.Diagnostics.CodeAnalysis;
910
using System.Linq;
1011
using System.Text.Json;
1112
using System.Text.Json.Serialization;
13+
1214
using Elastic.Transport;
1315

1416
namespace Elastic.Clients.Elasticsearch;
1517

1618
[JsonConverter(typeof(DataStreamNamesConverter))]
1719
[DebuggerDisplay("{DebugDisplay,nq}")]
18-
public sealed class DataStreamNames : IUrlParameter, IEnumerable<DataStreamName>, IEquatable<DataStreamNames>
20+
public sealed class DataStreamNames :
21+
IUrlParameter,
22+
IEnumerable<DataStreamName>,
23+
IEquatable<DataStreamNames>
24+
#if NET7_0_OR_GREATER
25+
, IParsable<DataStreamNames>
26+
#endif
1927
{
2028
internal readonly IList<DataStreamName> Names;
2129

@@ -96,6 +104,48 @@ public override int GetHashCode()
96104
}
97105

98106
string IUrlParameter.GetString(ITransportConfiguration? settings) => ToString();
107+
108+
#region IParsable
109+
110+
#if NET7_0_OR_GREATER
111+
112+
public static DataStreamNames Parse(string s, IFormatProvider? provider) =>
113+
TryParse(s, provider, out var result) ? result : throw new FormatException();
114+
115+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
116+
[NotNullWhen(true)] out DataStreamNames? result)
117+
{
118+
if (s is null)
119+
{
120+
result = null;
121+
return false;
122+
}
123+
124+
if (s.IsNullOrEmptyCommaSeparatedList(out var list))
125+
{
126+
result = new DataStreamNames();
127+
return true;
128+
}
129+
130+
var names = new List<DataStreamName>();
131+
foreach (var item in list)
132+
{
133+
if (!DataStreamName.TryParse(item, provider, out var name))
134+
{
135+
result = null;
136+
return false;
137+
}
138+
139+
names.Add(name);
140+
}
141+
142+
result = new DataStreamNames(names);
143+
return true;
144+
}
145+
146+
#endif
147+
148+
#endregion IParsable
99149
}
100150

101151
internal sealed class DataStreamNamesConverter : JsonConverter<DataStreamNames>

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Name.cs

+41-2
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,32 @@
44

55
using System;
66
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Text.Json.Serialization;
9+
810
using Elastic.Clients.Elasticsearch.Serialization;
911
using Elastic.Transport;
1012

1113
namespace Elastic.Clients.Elasticsearch;
1214

1315
[DebuggerDisplay("{DebugDisplay,nq}")]
1416
[JsonConverter(typeof(StringAliasConverter<Name>))]
15-
public sealed class Name : IEquatable<Name>, IUrlParameter
17+
public sealed class Name :
18+
IEquatable<Name>,
19+
IUrlParameter
20+
#if NET7_0_OR_GREATER
21+
, IParsable<Name>
22+
#endif
1623
{
17-
public Name(string name) => Value = name?.Trim();
24+
public Name(string name)
25+
{
26+
if (name is null)
27+
{
28+
throw new ArgumentNullException(nameof(name));
29+
}
30+
31+
Value = name.Trim();
32+
}
1833

1934
internal string Value { get; }
2035

@@ -48,4 +63,28 @@ public override int GetHashCode()
4863
return result;
4964
}
5065
}
66+
67+
#region IParsable
68+
69+
#if NET7_0_OR_GREATER
70+
71+
public static Name Parse(string s, IFormatProvider? provider) =>
72+
TryParse(s, provider, out var result) ? result : throw new FormatException();
73+
74+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
75+
[NotNullWhen(true)] out Name? result)
76+
{
77+
if (s is null)
78+
{
79+
result = null;
80+
return false;
81+
}
82+
83+
result = new Name(s);
84+
return true;
85+
}
86+
87+
#endif
88+
89+
#endregion IParsable
5190
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Core/UrlParameters/Name/Names.cs

+64-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Diagnostics;
8+
using System.Diagnostics.CodeAnalysis;
89
using System.Linq;
910
using System.Text.Json;
1011
using System.Text.Json.Serialization;
@@ -16,31 +17,40 @@ namespace Elastic.Clients.Elasticsearch;
1617

1718
[DebuggerDisplay("{DebugDisplay,nq}")]
1819
[JsonConverter(typeof(NamesConverter))]
19-
public sealed class Names : IEquatable<Names>, IUrlParameter
20+
public sealed class Names :
21+
IEquatable<Names>,
22+
IUrlParameter
23+
#if NET7_0_OR_GREATER
24+
, IParsable<Names>
25+
#endif
2026
{
21-
public Names(IEnumerable<string> names) : this(names?.Select(n => (Name)n).ToList())
27+
public Names()
2228
{
29+
Values = [];
2330
}
2431

2532
public Names(IEnumerable<Name> names)
2633
{
27-
Value = names?.ToList();
28-
if (!Value.HasAny())
29-
throw new ArgumentException($"can not create {nameof(Names)} on an empty enumerable of ", nameof(names));
34+
Values = names?.ToList();
3035
}
3136

32-
internal IList<Name> Value { get; }
37+
public Names(IEnumerable<string> names) :
38+
this(names?.Select(n => (Name)n).ToList())
39+
{
40+
}
41+
42+
internal IList<Name> Values { get; init; }
3343

3444
private string DebugDisplay => ((IUrlParameter)this).GetString(null);
3545

3646
public override string ToString() => DebugDisplay;
3747

38-
public bool Equals(Names other) => EqualsAllIds(Value, other.Value);
48+
public bool Equals(Names other) => EqualsAllIds(Values, other.Values);
3949

4050
string IUrlParameter.GetString(ITransportConfiguration? settings) =>
41-
string.Join(",", Value.Cast<IUrlParameter>().Select(n => n.GetString(settings)));
51+
string.Join(",", Values.Cast<IUrlParameter>().Select(n => n.GetString(settings)));
4252

43-
public static Names Parse(string names) => names.IsNullOrEmptyCommaSeparatedList(out var list) ? null : new Names(list);
53+
public static Names Parse(string names) => names.IsNullOrEmptyCommaSeparatedList(out var list) ? new Names() : new Names(list);
4454

4555
public static implicit operator Names(Name name) => name == null ? null : new Names(new[] { name });
4656

@@ -66,7 +76,49 @@ private static bool EqualsAllIds(ICollection<Name> thisIds, ICollection<Name> ot
6676

6777
public override bool Equals(object obj) => obj is string s ? Equals(Parse(s)) : obj is Names i && Equals(i);
6878

69-
public override int GetHashCode() => Value.GetHashCode();
79+
public override int GetHashCode() => Values.GetHashCode();
80+
81+
#region IParsable
82+
83+
#if NET7_0_OR_GREATER
84+
85+
public static Names Parse(string s, IFormatProvider? provider) =>
86+
TryParse(s, provider, out var result) ? result : throw new FormatException();
87+
88+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
89+
[NotNullWhen(true)] out Names? result)
90+
{
91+
if (s is null)
92+
{
93+
result = null;
94+
return false;
95+
}
96+
97+
if (s.IsNullOrEmptyCommaSeparatedList(out var list))
98+
{
99+
result = new Names();
100+
return true;
101+
}
102+
103+
var names = new List<Name>();
104+
foreach (var item in list)
105+
{
106+
if (!Name.TryParse(item, provider, out var name))
107+
{
108+
result = null;
109+
return false;
110+
}
111+
112+
names.Add(name);
113+
}
114+
115+
result = new Names { Values = names };
116+
return true;
117+
}
118+
119+
#endif
120+
121+
#endregion IParsable
70122
}
71123

72124
internal sealed class NamesConverter :
@@ -84,12 +136,12 @@ public override Names Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSe
84136

85137
public override void Write(Utf8JsonWriter writer, Names value, JsonSerializerOptions options)
86138
{
87-
if (value.Value is [{ } single])
139+
if (value.Values is [{ } single])
88140
{
89141
writer.WriteValue(options, single);
90142
return;
91143
}
92144

93-
writer.WriteValue(options, value.Value);
145+
writer.WriteValue(options, value.Values);
94146
}
95147
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Types/Core/Search/SourceConfigParam.cs

+40
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Diagnostics.CodeAnalysis;
67

78
using Elastic.Transport;
89

910
namespace Elastic.Clients.Elasticsearch.Core.Search;
1011

1112
public partial class SourceConfigParam :
1213
IUrlParameter
14+
#if NET7_0_OR_GREATER
15+
, IParsable<SourceConfigParam>
16+
#endif
1317
{
1418
public string GetString(ITransportConfiguration settings) =>
1519
Tag switch
@@ -18,4 +22,40 @@ public string GetString(ITransportConfiguration settings) =>
1822
1 => UrlFormatter.CreateString(Item2, settings)!,
1923
_ => throw new InvalidOperationException()
2024
};
25+
26+
#region IParsable
27+
28+
#if NET7_0_OR_GREATER
29+
30+
public static SourceConfigParam Parse(string s, IFormatProvider? provider) =>
31+
TryParse(s, provider, out var result) ? result : throw new FormatException();
32+
33+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
34+
[NotNullWhen(true)] out SourceConfigParam? result)
35+
{
36+
if (s is null)
37+
{
38+
result = null;
39+
return false;
40+
}
41+
42+
if (bool.TryParse(s, out var b))
43+
{
44+
result = new SourceConfigParam(b);
45+
return true;
46+
}
47+
48+
if (Fields.TryParse(s, provider, out var fields))
49+
{
50+
result = new SourceConfigParam(fields);
51+
return true;
52+
}
53+
54+
result = null;
55+
return false;
56+
}
57+
58+
#endif
59+
60+
#endregion IParsable
2161
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Types/Refresh.cs

+32-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,18 @@
22
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information.
44

5+
using System;
6+
using System.Diagnostics.CodeAnalysis;
7+
58
using Elastic.Transport;
69

710
namespace Elastic.Clients.Elasticsearch;
811

9-
public partial struct Refresh : IStringable
12+
public readonly struct Refresh :
13+
IStringable
14+
#if NET7_0_OR_GREATER
15+
, IParsable<Refresh>
16+
#endif
1017
{
1118
public static Refresh WaitFor = new("wait_for");
1219
public static Refresh True = new("true");
@@ -17,4 +24,28 @@ public partial struct Refresh : IStringable
1724
public string Value { get; }
1825

1926
public string GetString() => Value ?? string.Empty;
27+
28+
#region IParsable
29+
30+
#if NET7_0_OR_GREATER
31+
32+
public static Refresh Parse(string s, IFormatProvider? provider) =>
33+
TryParse(s, provider, out var result) ? result : throw new FormatException();
34+
35+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
36+
out Refresh result)
37+
{
38+
if (s is null)
39+
{
40+
result = default;
41+
return false;
42+
}
43+
44+
result = new Refresh(s);
45+
return true;
46+
}
47+
48+
#endif
49+
50+
#endregion IParsable
2051
}

‎src/Elastic.Clients.Elasticsearch/_Shared/Types/WaitForActiveShards.cs

+33-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,18 @@
22
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information.
44

5+
using System;
6+
using System.Diagnostics.CodeAnalysis;
7+
58
using Elastic.Transport;
69

710
namespace Elastic.Clients.Elasticsearch;
811

9-
public partial struct WaitForActiveShards : IStringable
12+
public readonly struct WaitForActiveShards :
13+
IStringable
14+
#if NET7_0_OR_GREATER
15+
, IParsable<WaitForActiveShards>
16+
#endif
1017
{
1118
public static WaitForActiveShards All = new("all");
1219

@@ -15,7 +22,32 @@ public partial struct WaitForActiveShards : IStringable
1522
public string Value { get; }
1623

1724
public static implicit operator WaitForActiveShards(int v) => new(v.ToString());
25+
1826
public static implicit operator WaitForActiveShards(string v) => new(v);
1927

2028
public string GetString() => Value ?? string.Empty;
29+
30+
#region IParsable
31+
32+
#if NET7_0_OR_GREATER
33+
34+
public static WaitForActiveShards Parse(string s, IFormatProvider? provider) =>
35+
TryParse(s, provider, out var result) ? result : throw new FormatException();
36+
37+
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider,
38+
out WaitForActiveShards result)
39+
{
40+
if (s is null)
41+
{
42+
result = default;
43+
return false;
44+
}
45+
46+
result = new WaitForActiveShards(s);
47+
return true;
48+
}
49+
50+
#endif
51+
52+
#endregion IParsable
2153
}

0 commit comments

Comments
 (0)
Please sign in to comment.