From 91b43790b3135675977af25c8462b9b6614655cb Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Wed, 20 Apr 2022 15:17:33 +0100 Subject: [PATCH] Add selector parameter for key, value, or both (resolves #3) Allows caller to specify a transformation to apply to key/value, presumably when either (or both) do not have an intended result of ToString --- .../DictionaryExtensions.cs | 163 ++++++++++++++++-- 1 file changed, 153 insertions(+), 10 deletions(-) diff --git a/X10D/src/DictionaryExtensions/DictionaryExtensions.cs b/X10D/src/DictionaryExtensions/DictionaryExtensions.cs index abb09eb..60306eb 100644 --- a/X10D/src/DictionaryExtensions/DictionaryExtensions.cs +++ b/X10D/src/DictionaryExtensions/DictionaryExtensions.cs @@ -29,20 +29,90 @@ public static class DictionaryExtensions return string.Empty; } - foreach (char character in value) - { - if (char.IsWhiteSpace(character)) - { - return $"\"{value}\""; - } - } - - return value; + return value.Contains(' ') ? $"\"{value}\"" : value; } static string GetQueryParameter(KeyValuePair pair) { - return $"{pair.Key}={SanitizeValue(pair.Value?.ToString())}"); + return $"{pair.Key}={SanitizeValue(pair.Value?.ToString())}"; + } + + return string.Join(';', source.Select(GetQueryParameter)); + } + + /// + /// Converts an of to an data connection + /// string. + /// + /// The type of the key element of the key/value pair. + /// The type of the value element of the key/value pair. + /// The source dictionary. + /// + /// A transform function to apply to the of each element. + /// + /// A representing the dictionary as a key=value set, concatenated with ;. + public static string ToConnectionString(this IEnumerable> source, + Func selector) + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + static string SanitizeValue(string? value) + { + if (value is null) + { + return string.Empty; + } + + return value.Contains(' ') ? $"\"{value}\"" : value; + } + + string GetQueryParameter(KeyValuePair pair) + { + return $"{pair.Key}={SanitizeValue(selector(pair.Value))}"; + } + + return string.Join(';', source.Select(GetQueryParameter)); + } + + /// + /// Converts an of to an data connection + /// string. + /// + /// The type of the key element of the key/value pair. + /// The type of the value element of the key/value pair. + /// The source dictionary. + /// + /// A transform function to apply to the of each element. + /// + /// + /// A transform function to apply to the of each element. + /// + /// A representing the dictionary as a key=value set, concatenated with ;. + public static string ToConnectionString(this IEnumerable> source, + Func keySelector, Func valueSelector) + where TKey : notnull + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + static string SanitizeValue(string? value) + { + if (value is null) + { + return string.Empty; + } + + return value.Contains(' ') ? $"\"{value}\"" : value; + } + + string GetQueryParameter(KeyValuePair pair) + { + return $"{keySelector(pair.Key)}={SanitizeValue(valueSelector(pair.Value))}"; } return string.Join(';', source.Select(GetQueryParameter)); @@ -72,4 +142,77 @@ public static class DictionaryExtensions return string.Join('&', source.Select(GetQueryParameter)); } + + /// + /// Converts an of to a HTTP GET query string. + /// + /// The type of the key element of the key/value pair. + /// The type of the value element of the key/value pair. + /// The source dictionary. + /// + /// A transform function to apply to the of each element. + /// + /// A representing the dictionary as a key=value set, concatenated with &. + public static string ToGetParameters(this IEnumerable> source, + Func selector) + where TKey : notnull + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (selector is null) + { + throw new ArgumentNullException(nameof(selector)); + } + + // can't static here because of 'selector' parameter + string GetQueryParameter(KeyValuePair pair) + { + string key = HttpUtility.UrlEncode(pair.Key.ToString())!; + string? value = HttpUtility.UrlEncode(selector(pair.Value)); + return $"{key}={value}"; + } + + return string.Join('&', source.Select(GetQueryParameter)); + } + + /// + /// Converts an of to a HTTP GET query string. + /// + /// The type of the key element of the key/value pair. + /// The type of the value element of the key/value pair. + /// The source dictionary. + /// + /// A transform function to apply to the of each element. + /// + /// + /// A transform function to apply to the of each element. + /// + /// A representing the dictionary as a key=value set, concatenated with &. + public static string ToGetParameters(this IEnumerable> source, + Func keySelector, Func valueSelector) + where TKey : notnull + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (valueSelector is null) + { + throw new ArgumentNullException(nameof(valueSelector)); + } + + // can't static here because of selector parameters + string GetQueryParameter(KeyValuePair pair) + { + string key = HttpUtility.UrlEncode(keySelector(pair.Key)); + string? value = HttpUtility.UrlEncode(valueSelector(pair.Value)); + return $"{key}={value}"; + } + + return string.Join('&', source.Select(GetQueryParameter)); + } }