From 536d7bfdb24ed3b4530fdf96d42900074fb99491 Mon Sep 17 00:00:00 2001 From: Albie Date: Thu, 24 Mar 2022 18:30:55 +0000 Subject: [PATCH 1/2] add support for non-string enumerable --- src/Utils/ParameterUtils.cs | 21 +++++++++++---------- tests/Requests/RequestTests.cs | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/Utils/ParameterUtils.cs b/src/Utils/ParameterUtils.cs index 588d816..f56627b 100644 --- a/src/Utils/ParameterUtils.cs +++ b/src/Utils/ParameterUtils.cs @@ -45,7 +45,7 @@ internal static IEnumerable> GetParameter(object // check if the type we've got is an IEnumerable of anything AND we have a valid collection handler mode if (attribute.CollectionHandling.HasValue && typeof(IEnumerable).IsAssignableFrom(property.PropertyType)) { - Func, string, CultureInfo, IEnumerable>> entityConverter = attribute.CollectionHandling switch + Func>> entityConverter = attribute.CollectionHandling switch { CollectionConversionMode.Recursive => ApplyRecursiveConversion, CollectionConversionMode.Unordered => ApplyUnorderedConversion, @@ -55,7 +55,7 @@ internal static IEnumerable> GetParameter(object _ => throw new ArgumentOutOfRangeException() }; - foreach (var entry in entityConverter.Invoke((IEnumerable)propertyValue, keyName, culture)) + foreach (var entry in entityConverter.Invoke((IEnumerable)propertyValue, keyName, culture)) // we purposely keep nulls in here, as it might affect the ordering. { yield return entry; @@ -102,17 +102,17 @@ internal static object GetSingleParameterObject(object host) where T : Attrib return attributedProperty.GetValue(host); } - private static IEnumerable> ApplyRecursiveConversion(IEnumerable values, string keyName, CultureInfo culture) + private static IEnumerable> ApplyRecursiveConversion(IEnumerable values, string keyName, CultureInfo culture) { - return values.Select(x => x.ToKeyValuePair(keyName, culture)); + return values.Cast().Select(x => x.ToKeyValuePair(keyName, culture)); } - private static IEnumerable> ApplyUnorderedConversion(IEnumerable values, string keyName, CultureInfo culture) + private static IEnumerable> ApplyUnorderedConversion(IEnumerable values, string keyName, CultureInfo culture) { - return values.Select(x => x.ToKeyValuePair($"{keyName}[]", culture)); + return values.Cast().Select(x => x.ToKeyValuePair($"{keyName}[]", culture)); } - private static IEnumerable> ApplyOrderedConversion(IEnumerable values, string keyName, CultureInfo culture) + private static IEnumerable> ApplyOrderedConversion(IEnumerable values, string keyName, CultureInfo culture) { var counter = 0; var enumerator = values.GetEnumerator(); @@ -122,12 +122,13 @@ private static IEnumerable> ApplyOrderedConversion( yield return enumerator.Current.ToKeyValuePair($"{keyName}[{counter++}]", culture); } - enumerator.Dispose(); + // dispose if possible + (enumerator as IDisposable)?.Dispose(); } - private static IEnumerable> ApplyConcatenation(IEnumerable values, string keyName, CultureInfo culture, string concatCharacter) + private static IEnumerable> ApplyConcatenation(IEnumerable values, string keyName, CultureInfo culture, string concatCharacter) { - yield return new KeyValuePair(keyName, string.Join(concatCharacter, values.Select(x => x.AsString(culture)))); + yield return new KeyValuePair(keyName, string.Join(concatCharacter, values.Cast().Select(x => x.AsString(culture)))); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/tests/Requests/RequestTests.cs b/tests/Requests/RequestTests.cs index dda046c..c17e8e7 100644 --- a/tests/Requests/RequestTests.cs +++ b/tests/Requests/RequestTests.cs @@ -1,10 +1,13 @@ // DragonFruit.Data Copyright DragonFruit Network // Licensed under the MIT License. Please refer to the LICENSE file at the root of this project for details +using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; using DragonFruit.Data.Basic; +using DragonFruit.Data.Parameters; using NUnit.Framework; namespace DragonFruit.Data.Tests.Requests @@ -48,5 +51,25 @@ public void TestSyncHttp2Request() Assert.IsTrue(result.IsSuccessStatusCode); Assert.AreEqual(request.Version, result.Version); } + + [Test] + public void TestConcatEnumerable() + { + var req = new EnumerableTest(Enumerable.Range(1, 5)); + Assert.True(req.FullUrl.Contains("1,2,3")); + } + + private class EnumerableTest : ApiRequest + { + public override string Path => "https://example.com"; + + public EnumerableTest(IEnumerable data) + { + Data = data; + } + + [QueryParameter("data", CollectionConversionMode.Concatenated)] + public IEnumerable Data { get; set; } + } } } From 080f53bc177f0ef7985dab2060935893540eec7c Mon Sep 17 00:00:00 2001 From: Albie Date: Thu, 24 Mar 2022 18:37:46 +0000 Subject: [PATCH 2/2] reduce static function members --- src/Utils/ParameterUtils.cs | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/Utils/ParameterUtils.cs b/src/Utils/ParameterUtils.cs index f56627b..d4f8ce8 100644 --- a/src/Utils/ParameterUtils.cs +++ b/src/Utils/ParameterUtils.cs @@ -45,18 +45,18 @@ internal static IEnumerable> GetParameter(object // check if the type we've got is an IEnumerable of anything AND we have a valid collection handler mode if (attribute.CollectionHandling.HasValue && typeof(IEnumerable).IsAssignableFrom(property.PropertyType)) { - Func>> entityConverter = attribute.CollectionHandling switch + Func>> entityConverter = attribute.CollectionHandling switch { - CollectionConversionMode.Recursive => ApplyRecursiveConversion, - CollectionConversionMode.Unordered => ApplyUnorderedConversion, - CollectionConversionMode.Ordered => ApplyOrderedConversion, - CollectionConversionMode.Concatenated => (a, b, c) => ApplyConcatenation(a, b, c, attribute.CollectionSeparator ?? DefaultConcatenationCharacter), + CollectionConversionMode.Ordered => values => ApplyOrderedConversion(values, keyName, culture), + CollectionConversionMode.Recursive => values => values.Cast().Select(x => x.ToKeyValuePair(keyName, culture)), + CollectionConversionMode.Unordered => values => values.Cast().Select(x => x.ToKeyValuePair($"{keyName}[]", culture)), + CollectionConversionMode.Concatenated => values => ApplyConcatenation(values, keyName, culture, attribute.CollectionSeparator ?? DefaultConcatenationCharacter), _ => throw new ArgumentOutOfRangeException() }; - foreach (var entry in entityConverter.Invoke((IEnumerable)propertyValue, keyName, culture)) - // we purposely keep nulls in here, as it might affect the ordering. + // we purposely keep nulls in here, as it might affect the ordering. + foreach (var entry in entityConverter.Invoke((IEnumerable)propertyValue)) { yield return entry; } @@ -102,16 +102,6 @@ internal static object GetSingleParameterObject(object host) where T : Attrib return attributedProperty.GetValue(host); } - private static IEnumerable> ApplyRecursiveConversion(IEnumerable values, string keyName, CultureInfo culture) - { - return values.Cast().Select(x => x.ToKeyValuePair(keyName, culture)); - } - - private static IEnumerable> ApplyUnorderedConversion(IEnumerable values, string keyName, CultureInfo culture) - { - return values.Cast().Select(x => x.ToKeyValuePair($"{keyName}[]", culture)); - } - private static IEnumerable> ApplyOrderedConversion(IEnumerable values, string keyName, CultureInfo culture) { var counter = 0;