Add Parse(string, IFormatProvider) handling to option converter

This commit is contained in:
Alexey Golub
2019-07-28 23:07:42 +03:00
parent 9856e784f5
commit 5174d5354b
2 changed files with 40 additions and 5 deletions

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using CliFx.Models; using CliFx.Models;
using CliFx.Services; using CliFx.Services;
using FluentAssertions; using FluentAssertions;
@@ -10,14 +11,14 @@ namespace CliFx.Tests
{ {
public partial class CommandOptionInputConverterTests public partial class CommandOptionInputConverterTests
{ {
public enum TestEnum private enum TestEnum
{ {
Value1, Value1,
Value2, Value2,
Value3 Value3
} }
public struct TestStringConstructable private class TestStringConstructable
{ {
public string Value { get; } public string Value { get; }
@@ -27,7 +28,7 @@ namespace CliFx.Tests
} }
} }
public struct TestStringParseable private class TestStringParseable
{ {
public string Value { get; } public string Value { get; }
@@ -38,6 +39,19 @@ namespace CliFx.Tests
public static TestStringParseable Parse(string value) => new TestStringParseable(value); public static TestStringParseable Parse(string value) => new TestStringParseable(value);
} }
private class TestStringParseableWithFormatProvider
{
public string Value { get; }
private TestStringParseableWithFormatProvider(string value)
{
Value = value;
}
public static TestStringParseableWithFormatProvider Parse(string value, IFormatProvider formatProvider) =>
new TestStringParseableWithFormatProvider(value);
}
} }
[TestFixture] [TestFixture]
@@ -159,6 +173,12 @@ namespace CliFx.Tests
TestStringParseable.Parse("value") TestStringParseable.Parse("value")
); );
yield return new TestCaseData(
new CommandOptionInput("option", "value"),
typeof(TestStringParseableWithFormatProvider),
TestStringParseableWithFormatProvider.Parse("value", CultureInfo.InvariantCulture)
);
yield return new TestCaseData( yield return new TestCaseData(
new CommandOptionInput("option", new[] {"value1", "value2"}), new CommandOptionInput("option", new[] {"value1", "value2"}),
typeof(string[]), typeof(string[]),

View File

@@ -22,6 +22,14 @@ namespace CliFx.Services
{ {
} }
private ConstructorInfo GetStringConstructor(Type type) => type.GetConstructor(new[] {typeof(string)});
private MethodInfo GetStaticParseMethod(Type type) =>
type.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new[] {typeof(string)}, null);
private MethodInfo GetStaticParseMethodWithFormatProvider(Type type) =>
type.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new[] {typeof(string), typeof(IFormatProvider)}, null);
private object ConvertValue(string value, Type targetType) private object ConvertValue(string value, Type targetType)
{ {
// String or object // String or object
@@ -199,14 +207,21 @@ namespace CliFx.Services
} }
// Has a constructor that accepts a single string // Has a constructor that accepts a single string
var stringConstructor = targetType.GetConstructor(new[] {typeof(string)}); var stringConstructor = GetStringConstructor(targetType);
if (stringConstructor != null) if (stringConstructor != null)
{ {
return stringConstructor.Invoke(new object[] {value}); return stringConstructor.Invoke(new object[] {value});
} }
// Has a static parse method that accepts a single string and a format provider
var parseMethodWithFormatProvider = GetStaticParseMethodWithFormatProvider(targetType);
if (parseMethodWithFormatProvider != null)
{
return parseMethodWithFormatProvider.Invoke(null, new object[] { value, _formatProvider });
}
// Has a static parse method that accepts a single string // Has a static parse method that accepts a single string
var parseMethod = targetType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new[] {typeof(string)}, null); var parseMethod = GetStaticParseMethod(targetType);
if (parseMethod != null) if (parseMethod != null)
{ {
return parseMethod.Invoke(null, new object[] {value}); return parseMethod.Invoke(null, new object[] {value});