Skip to content

Commit

Permalink
Added array parsing to AddObject with []
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyzimarev committed Jun 7, 2022
1 parent 39e6e7d commit 644912d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 11 deletions.
33 changes: 24 additions & 9 deletions src/RestSharp/Parameters/ObjectParser.cs
Expand Up @@ -23,34 +23,45 @@ static class ObjectParser {
var type = obj.GetType();
var props = type.GetProperties();

var properties = new List<(string Name, string? Value)>();

foreach (var prop in props.Where(x => IsAllowedProperty(x.Name))) {
var val = prop.GetValue(obj, null);

if (val == null) continue;

yield return prop.PropertyType.IsArray
? GetArray(prop, val)
: GetValue(prop, val);
if (prop.PropertyType.IsArray)
properties.AddRange(GetArray(prop, val));
else
properties.Add(GetValue(prop, val));
}

string? ParseValue(string? format, object? value) => format == null ? value?.ToString() : string.Format($"{{0:{format}}}", value);

(string, string?) GetArray(PropertyInfo propertyInfo, object? value) {
IEnumerable<(string, string?)> GetArray(PropertyInfo propertyInfo, object? value) {
var elementType = propertyInfo.PropertyType.GetElementType();
var array = (Array)value!;

var attribute = propertyInfo.GetCustomAttribute<RequestPropertyAttribute>();
var name = attribute?.Name ?? propertyInfo.Name;

var queryType = attribute?.ArrayQueryType ?? RequestArrayQueryType.CommaSeparated;

if (array.Length > 0 && elementType != null) {
// convert the array to an array of strings
var values = array
.Cast<object>()
.Select(item => ParseValue(attribute?.Format, item));
return (name, string.Join(",", values));

return queryType switch {
RequestArrayQueryType.CommaSeparated => new (string, string?)[] { (name, string.Join(",", values)) },
RequestArrayQueryType.ArrayParameters => values.Select(x => ($"{name}[]", x)),
_ => throw new ArgumentOutOfRangeException()
};

}

return (name, null);
return new (string, string?)[] { (name, null) };
}

(string, string?) GetValue(PropertyInfo propertyInfo, object? value) {
Expand All @@ -62,12 +73,16 @@ static class ObjectParser {

bool IsAllowedProperty(string propertyName)
=> includedProperties.Length == 0 || includedProperties.Length > 0 && includedProperties.Contains(propertyName);

return properties;
}
}

[AttributeUsage(AttributeTargets.Property)]
public class RequestPropertyAttribute : Attribute {
public string? Name { get; set; }

public string? Format { get; set; }
public string? Name { get; set; }
public string? Format { get; set; }
public RequestArrayQueryType ArrayQueryType { get; set; } = RequestArrayQueryType.CommaSeparated;
}

public enum RequestArrayQueryType { CommaSeparated, ArrayParameters }
21 changes: 19 additions & 2 deletions test/RestSharp.Tests/ObjectParserTests.cs
Expand Up @@ -7,6 +7,7 @@ public class ObjectParserTests {
public void ShouldUseRequestProperty() {
var now = DateTime.Now;
var dates = new[] { now, now.AddDays(1), now.AddDays(2) };

var request = new TestObject {
SomeData = "test",
SomeDate = now,
Expand All @@ -24,17 +25,33 @@ public class ObjectParserTests {
parsed["dates"].Should().Be(string.Join(",", dates.Select(x => x.ToString("d"))));
}

[Fact]
public void ShouldProduceMultipleParametersForArray() {
var request = new AnotherTestObject {
SomeIds = new[] { 1, 2, 3 }
};
var expected = request.SomeIds.Select(x => ("ids[]", x.ToString()));
var parsed = request.GetProperties();

parsed.Should().BeEquivalentTo(expected);
}

class AnotherTestObject {
[RequestProperty(Name = "ids", ArrayQueryType = RequestArrayQueryType.ArrayParameters)]
public int[] SomeIds { get; set; }
}

class TestObject {
[RequestProperty(Name = "some_data")]
public string SomeData { get; set; }

[RequestProperty(Format = "d")]
public DateTime SomeDate { get; set; }

[RequestProperty(Name = "dates", Format = "d")]
public DateTime[] DatesArray { get; set; }

public int Plain { get; set; }
public int Plain { get; set; }
public DateTime[] PlainArray { get; set; }
}
}

0 comments on commit 644912d

Please sign in to comment.