3
3
// See the LICENSE file in the project root for more information
4
4
5
5
using System ;
6
- using System . Collections . Generic ;
7
- using System . Linq ;
6
+ using System . Collections ;
8
7
using System . Runtime . Serialization ;
8
+ using System . Text ;
9
9
using Elastic . Transport . Extensions ;
10
10
11
11
namespace Elastic . Transport ;
@@ -22,59 +22,113 @@ public sealed class UrlFormatter : IFormatProvider, ICustomFormatter
22
22
public UrlFormatter ( ITransportConfiguration settings ) => _settings = settings ;
23
23
24
24
/// <inheritdoc cref="ICustomFormatter.Format"/>>
25
- public string Format ( string format , object arg , IFormatProvider formatProvider )
25
+ public string Format ( string ? format , object ? arg , IFormatProvider ? formatProvider )
26
26
{
27
27
if ( arg == null ) throw new ArgumentNullException ( ) ;
28
28
29
- if ( format == "r" ) return arg . ToString ( ) ;
29
+ if ( format == "r" ) return arg . ToString ( ) ?? string . Empty ;
30
30
31
31
var value = CreateString ( arg , _settings ) ;
32
32
if ( value . IsNullOrEmpty ( ) && ! format . IsNullOrEmpty ( ) )
33
33
throw new ArgumentException ( $ "The parameter: { format } to the url is null or empty") ;
34
34
35
- return value . IsNullOrEmpty ( ) ? string . Empty : Uri . EscapeDataString ( value ) ;
35
+ return string . IsNullOrEmpty ( value ) ? string . Empty : Uri . EscapeDataString ( value ) ;
36
36
}
37
37
38
38
/// <inheritdoc cref="IFormatProvider.GetFormat"/>
39
- public object GetFormat ( Type formatType ) => formatType == typeof ( ICustomFormatter ) ? this : null ;
39
+ public object ? GetFormat ( Type formatType ) => formatType == typeof ( ICustomFormatter ) ? this : null ;
40
40
41
41
/// <inheritdoc cref="CreateString(object, ITransportConfiguration)"/>
42
- public string CreateString ( object value ) => CreateString ( value , _settings ) ;
42
+ public string ? CreateString ( object ? value ) => CreateString ( value , _settings ) ;
43
43
44
44
/// <summary> Creates a query string representation for <paramref name="value"/> </summary>
45
- public static string ? CreateString ( object ? value , ITransportConfiguration settings )
45
+ public static string ? CreateString ( object ? value , ITransportConfiguration settings ) =>
46
+ value switch
47
+ {
48
+ null => null ,
49
+ string s => s ,
50
+ string [ ] ss => string . Join ( "," , ss ) ,
51
+ Enum e => e . GetStringValue ( ) ,
52
+ bool b => b ? "true" : "false" ,
53
+ DateTimeOffset offset => offset . ToString ( "o" ) ,
54
+ TimeSpan timeSpan => timeSpan . ToTimeUnit ( ) ,
55
+ // Special handling to support non-zero based arrays
56
+ Array pns => CreateStringFromArray ( pns , settings ) ,
57
+ // Performance optimization for directly indexable collections
58
+ IList pns => CreateStringFromIList ( pns , settings ) ,
59
+ // Generic implementation for all other collections
60
+ IEnumerable pns => CreateStringFromIEnumerable ( pns , settings ) ,
61
+ _ => ResolveUrlParameterOrDefault ( value , settings )
62
+ } ;
63
+
64
+ private static string CreateStringFromArray ( Array value , ITransportConfiguration settings )
46
65
{
47
- switch ( value )
66
+ switch ( value . Length )
67
+ {
68
+ case 0 :
69
+ return string . Empty ;
70
+ case 1 :
71
+ return ResolveUrlParameterOrDefault ( value . GetValue ( value . GetLowerBound ( 0 ) ) , settings ) ;
72
+ }
73
+
74
+ var sb = new StringBuilder ( ) ;
75
+
76
+ for ( var i = value . GetLowerBound ( 0 ) ; i <= value . GetUpperBound ( 0 ) ; ++ i )
48
77
{
49
- case null : return null ;
50
- case string s : return s ;
51
- case string [ ] ss : return string . Join ( "," , ss ) ;
52
- case Enum e : return e . GetStringValue ( ) ;
53
- case bool b : return b ? "true" : "false" ;
54
- case DateTimeOffset offset : return offset . ToString ( "o" ) ;
55
- case IEnumerable < object > pns :
56
- return CreateStringFromIEnumerable ( pns , settings ) ;
57
-
58
- case Array pns :
59
- return CreateStringFromIEnumerable ( ConvertArrayToEnumerable ( pns ) , settings ) ;
60
-
61
- case TimeSpan timeSpan : return timeSpan . ToTimeUnit ( ) ;
62
- default :
63
- return ResolveUrlParameterOrDefault ( value , settings ) ;
78
+ if ( sb . Length != 0 )
79
+ sb . Append ( ',' ) ;
80
+
81
+ sb . Append ( ResolveUrlParameterOrDefault ( value . GetValue ( i ) , settings ) ) ;
64
82
}
83
+
84
+ return sb . ToString ( ) ;
65
85
}
66
86
67
- private static string CreateStringFromIEnumerable ( IEnumerable < object > value , ITransportConfiguration settings ) =>
68
- string . Join ( "," , value . Select ( o => ResolveUrlParameterOrDefault ( o , settings ) ) ) ;
87
+ private static string CreateStringFromIList ( IList value , ITransportConfiguration settings )
88
+ {
89
+ switch ( value . Count )
90
+ {
91
+ case 0 :
92
+ return string . Empty ;
93
+ case 1 :
94
+ return ResolveUrlParameterOrDefault ( value [ 0 ] , settings ) ;
95
+ }
96
+
97
+ var sb = new StringBuilder ( ) ;
69
98
70
- private static IEnumerable < object > ConvertArrayToEnumerable ( Array array )
99
+ for ( var i = 0 ; i < value . Count ; ++ i )
100
+ {
101
+ if ( sb . Length != 0 )
102
+ sb . Append ( ',' ) ;
103
+
104
+ sb . Append ( ResolveUrlParameterOrDefault ( value [ i ] , settings ) ) ;
105
+ }
106
+
107
+ return sb . ToString ( ) ;
108
+ }
109
+
110
+ private static string CreateStringFromIEnumerable ( IEnumerable value , ITransportConfiguration settings )
71
111
{
72
- for ( var i = array . GetLowerBound ( 0 ) ; i <= array . GetUpperBound ( 0 ) ; i ++ )
73
- yield return array . GetValue ( i ) ;
112
+ var sb = new StringBuilder ( ) ;
113
+
114
+ foreach ( var v in value )
115
+ {
116
+ if ( sb . Length != 0 )
117
+ sb . Append ( ',' ) ;
118
+
119
+ sb . Append ( ResolveUrlParameterOrDefault ( v , settings ) ) ;
120
+ }
121
+
122
+ return sb . ToString ( ) ;
74
123
}
75
124
76
- private static string ResolveUrlParameterOrDefault ( object value , ITransportConfiguration settings ) =>
77
- value is IUrlParameter urlParam ? urlParam . GetString ( settings ) : GetEnumMemberName ( value ) ?? value . ToString ( ) ;
125
+ private static string ResolveUrlParameterOrDefault ( object ? value , ITransportConfiguration settings ) =>
126
+ value switch
127
+ {
128
+ null => string . Empty ,
129
+ IUrlParameter urlParam => urlParam . GetString ( settings ) ,
130
+ _ => GetEnumMemberName ( value ) ?? value . ToString ( ) ?? string . Empty
131
+ } ;
78
132
79
133
private static string ? GetEnumMemberName ( object value )
80
134
{
0 commit comments