/src/OpenWrap/PackageManagement/Exporters/StringConversion.cs

https://github.com/rvdginste/openwrap
C# | 110 lines | 102 code | 8 blank | 0 comment | 17 complexity | 2ecbfbade69f038a9dd6aada7a1693ac MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. namespace OpenWrap.PackageManagement.Exporters
  7. {
  8. public static class StringConversion
  9. {
  10. delegate bool Converter(IEnumerable<string> values, out object result);
  11. static readonly Dictionary<Type, Converter> _converters = new Dictionary<Type, Converter>
  12. {
  13. {typeof(string), ConvertString},
  14. {typeof(IEnumerable<string>), ConvertListOfString},
  15. {typeof(Version), ConvertVersion}
  16. };
  17. static bool ConvertVersion(IEnumerable<string> values, out object result)
  18. {
  19. result = null;
  20. if (values.Count() != 1) return false;
  21. try
  22. {
  23. result = new Version(values.Single());
  24. }
  25. catch
  26. {
  27. return false;
  28. }
  29. return true;
  30. }
  31. static bool ConvertListOfString(IEnumerable<string> values, out object result)
  32. {
  33. result = values;
  34. return true;
  35. }
  36. static bool ConvertString(IEnumerable<string> values, out object result)
  37. {
  38. result = null;
  39. if (values.Count() != 1) return false;
  40. result = values.First();
  41. return true;
  42. }
  43. static Converter FallbackConverter(Type destinationType)
  44. {
  45. return (IEnumerable<string> values, out object result) => ConvertObject(destinationType, values, out result);
  46. }
  47. public static bool TryConvert(Type destinationType, IEnumerable<string> values, out object result)
  48. {
  49. return GetConverter(destinationType)(values, out result);
  50. }
  51. static Converter GetConverter(Type destinationType)
  52. {
  53. return _converters.ContainsKey(destinationType)
  54. ? _converters[destinationType]
  55. : FallbackConverter(destinationType);
  56. }
  57. static bool ConvertObject(Type destinationType, IEnumerable<string> values, out object result)
  58. {
  59. result = null;
  60. var enumerableTypes = (from type in destinationType.GetInterfaces()
  61. where type.IsGenericType
  62. let def = type.GetGenericTypeDefinition()
  63. where def == typeof(IEnumerable<>)
  64. select type.GetGenericArguments().Single()).ToList();
  65. var enumType = destinationType.IsInterface && destinationType.IsGenericType && destinationType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
  66. ? destinationType.GetGenericArguments().Single()
  67. : null;
  68. if (enumType != null)
  69. {
  70. var converter = GetConverter(enumType);
  71. var list = Activator.CreateInstance(typeof(List<>).MakeGenericType(enumType)) as IList;
  72. foreach (var value in values)
  73. {
  74. object convertedValue;
  75. if (converter(new[] { value }, out convertedValue))
  76. list.Add(convertedValue);
  77. else return false;
  78. }
  79. result = list;
  80. return true;
  81. }
  82. if (values.Count() != 1)
  83. return false;
  84. var valueToConvert = values.Single();
  85. try
  86. {
  87. result = Convert.ChangeType(valueToConvert, destinationType);
  88. return true;
  89. }
  90. catch { }
  91. var typeConverter = TypeDescriptor.GetConverter(destinationType);
  92. if (typeConverter == null || !typeConverter.CanConvertFrom(typeof(string))) return false;
  93. try
  94. {
  95. result = typeConverter.ConvertFromString(valueToConvert);
  96. return true;
  97. }
  98. catch { }
  99. return false;
  100. }
  101. }
  102. }