PageRenderTime 59ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/CommandLineParser/CommandLineParser_4.0/Arguments/EnumeratedValueArgument.cs

#
C# | 225 lines | 109 code | 17 blank | 99 comment | 1 complexity | 816c3dc07150588967a22e9ac51002fe MD5 | raw file
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Reflection;
  6. using CommandLineParser.Arguments;
  7. using CommandLineParser.Exceptions;
  8. namespace CommandLineParser.Arguments
  9. {
  10. /// <summary>
  11. /// Use EnumeratedValueArgument for an argument whose values must be from certain finite set
  12. /// (see <see cref="AllowedValues"/>)
  13. /// </summary>
  14. /// <typeparam name="TValue">Type of the value</typeparam>
  15. /// <include file='Doc\CommandLineParser.xml' path='CommandLineParser/Arguments/EnumeratedValueArgument/*'/>
  16. public class EnumeratedValueArgument<TValue>:
  17. CertifiedValueArgument<TValue>
  18. {
  19. private ICollection<TValue> allowedValues;
  20. /// <summary>
  21. /// Set of values that are allowed for the argument.
  22. /// </summary>
  23. public ICollection<TValue> AllowedValues
  24. {
  25. get { return allowedValues; }
  26. set { allowedValues = value; }
  27. }
  28. /// <summary>
  29. /// Initilazes <see cref="AllowedValues"/> by a string of values separated by commas or semicolons.
  30. /// </summary>
  31. /// <param name="valuesString">Allowed values (separated by comas or semicolons)</param>
  32. public void InitAllowedValues(string valuesString)
  33. {
  34. string[] splitted = valuesString.Split(';', ',');
  35. TValue[] typedValues = new TValue[splitted.Length];
  36. int i = 0;
  37. foreach (string value in splitted)
  38. {
  39. typedValues[i] = Convert(value);
  40. i++;
  41. }
  42. AllowedValues = typedValues;
  43. }
  44. #region constructor
  45. /// <summary>
  46. /// Creates new command line argument with a <see cref="Argument.ShortName">short name</see>.
  47. /// </summary>
  48. /// <param name="shortName">Short name of the argument</param>
  49. public EnumeratedValueArgument(char shortName)
  50. : base(shortName)
  51. {
  52. this.allowedValues = new TValue[0];
  53. }
  54. /// <summary>
  55. /// Creates new command line argument with a <see cref="Argument.ShortName">short name</see>
  56. /// and <see cref="Argument.LongName">long name</see>.
  57. /// </summary>
  58. /// <param name="shortName">Short name of the argument</param>
  59. /// <param name="longName">Long name of the argument </param>
  60. public EnumeratedValueArgument(char shortName, string longName)
  61. : base(shortName, longName)
  62. {
  63. this.allowedValues = new TValue[0];
  64. }
  65. /// <summary>
  66. /// Creates new command line argument with a <see cref="Argument.ShortName">short name</see>.
  67. /// </summary>
  68. /// <param name="shortName">Short name of the argument</param>
  69. /// <param name="allowedValues">Allowed values</param>
  70. public EnumeratedValueArgument(char shortName, ICollection<TValue> allowedValues)
  71. : base(shortName)
  72. {
  73. this.allowedValues = allowedValues;
  74. }
  75. /// <summary>
  76. /// Creates new command line argument with a <see cref="Argument.ShortName">short name</see>
  77. /// and <see cref="Argument.LongName">long name</see>.
  78. /// </summary>
  79. /// <param name="shortName">Short name of the argument</param>
  80. /// <param name="longName">Long name of the argument </param>
  81. /// <param name="allowedValues">Allowed values</param>
  82. public EnumeratedValueArgument(char shortName, string longName, ICollection<TValue> allowedValues)
  83. : base(shortName, longName)
  84. {
  85. this.allowedValues = allowedValues;
  86. }
  87. /// <summary>
  88. /// Creates new command line argument with a <see cref="Argument.ShortName">short name</see>,
  89. /// <see cref="Argument.LongName">long name</see> and <see cref="Argument.Description">description</see>
  90. /// </summary>
  91. /// <param name="shortName">Short name of the argument</param>
  92. /// <param name="longName">Long name of the argument </param>
  93. /// <param name="description">Description of the argument</param>
  94. /// <param name="allowedValues">Allowed values</param>
  95. public EnumeratedValueArgument(char shortName, string longName, string description, ICollection<TValue> allowedValues)
  96. : base(shortName, longName, description)
  97. {
  98. this.allowedValues = allowedValues;
  99. }
  100. #endregion
  101. /// <summary>
  102. /// Checks whether the specified value belongs to
  103. /// the set of <see cref="AllowedValues">allowed values</see>.
  104. /// </summary>
  105. /// <param name="value">value to certify</param>
  106. /// <exception cref="CommandLineArgumentOutOfRangeException">thrown when <paramref name="value"/> does not belong to the set of allowed values.</exception>
  107. internal override void Certify(TValue value)
  108. {
  109. if (!allowedValues.Contains(Value))
  110. throw new CommandLineArgumentOutOfRangeException(String.Format(
  111. Messages.EXC_ARG_ENUM_OUT_OF_RANGE, Value,
  112. Name), Name);
  113. }
  114. }
  115. /// <summary>
  116. /// <para>
  117. /// Attribute for declaring a class' field a <see cref="EnumeratedValueArgument{TValue}"/> and
  118. /// thus binding a field's value to a certain command line switch argument.
  119. /// </para>
  120. /// <para>
  121. /// Instead of creating an argument explicitly, you can assign a class' field an argument
  122. /// attribute and let the CommandLineParse take care of binding the attribute to the field.
  123. /// </para>
  124. /// </summary>
  125. /// <remarks>Appliable to fields and properties (public).</remarks>
  126. /// <remarks>Use <see cref="CommandLineParser.ExtractArgumentAttributes"/> for each object
  127. /// you where you have delcared argument attributes.</remarks>
  128. /// <example>
  129. /// <code source="Examples\AttributeExample.cs" lang="cs" title="Example of declaring argument attributes" />
  130. /// </example>
  131. public sealed class EnumeratedValueArgumentAttribute : ArgumentAttribute
  132. {
  133. private Type argumentType;
  134. /// <summary>
  135. /// Creates proper generic <see cref="BoundedValueArgument{TValue}"/> type for <paramref name="type"/>.
  136. /// </summary>
  137. /// <param name="type">type of the argument value</param>
  138. /// <returns>generic type</returns>
  139. private static Type CreateProperValueArgumentType(Type type)
  140. {
  141. Type genericType = typeof(EnumeratedValueArgument<>);
  142. Type constructedType = genericType.MakeGenericType(type);
  143. return constructedType;
  144. }
  145. /// <summary>
  146. /// Creates new instance of EnumeratedValueArgumentAttribute. EnumeratedValueArgument
  147. /// uses underlaying <see cref="EnumeratedValueArgument{TValue}"/>.
  148. /// </summary>
  149. /// <param name="type">Type of the generic parameter of <see cref="EnumeratedValueArgument{TValue}"/>.</param>
  150. /// <param name="shortName"><see cref="Argument.ShortName">short name</see> of the underlying argument</param>
  151. /// <remarks>
  152. /// Parameter <paramref name="type"/> has to be either built-in
  153. /// type or has to define a static Parse(String, CultureInfo)
  154. /// method for reading the value from string.
  155. /// </remarks>
  156. public EnumeratedValueArgumentAttribute(Type type, char shortName)
  157. : base(CreateProperValueArgumentType(type), shortName)
  158. {
  159. argumentType = CreateProperValueArgumentType(type);
  160. }
  161. /// <summary>
  162. /// Creates new instance of EnumeratedValueArgument. EnumeratedValueArgument
  163. /// uses underlaying <see cref="EnumeratedValueArgument{TValue}"/>.
  164. /// </summary>
  165. /// <param name="type">Type of the generic parameter of <see cref="EnumeratedValueArgument{TValue}"/>.</param>
  166. /// <param name="shortName"><see cref="Argument.ShortName">short name</see> of the underlying argument</param>
  167. /// <param name="longName"><see cref="Argument.LongName">long name</see> of the underlying argument</param>
  168. /// <remarks>
  169. /// Parameter <paramref name="type"/> has to be either built-in
  170. /// type or has to define a static Parse(String, CultureInfo)
  171. /// method for reading the value from string.
  172. /// </remarks>
  173. public EnumeratedValueArgumentAttribute(Type type, char shortName, string longName)
  174. : base(CreateProperValueArgumentType(type), shortName, longName)
  175. {
  176. argumentType = CreateProperValueArgumentType(type);
  177. }
  178. /// <summary>
  179. /// Allowed values of the argument, separated by commas or semicolons.
  180. /// </summary>
  181. public string AllowedValues
  182. {
  183. get
  184. {
  185. return String.Empty;
  186. }
  187. set
  188. {
  189. argumentType.InvokeMember(
  190. "InitAllowedValues", BindingFlags.InvokeMethod, null, Argument, new object[] {value});
  191. }
  192. }
  193. /// <summary>
  194. /// Default value
  195. /// </summary>
  196. public object DefaultValue
  197. {
  198. get
  199. {
  200. return argumentType.InvokeMember("DefaultValue", BindingFlags.GetProperty, null, Argument, null);
  201. }
  202. set
  203. {
  204. argumentType.InvokeMember("DefaultValue", BindingFlags.SetProperty, null, Argument, new[] { value });
  205. }
  206. }
  207. }
  208. }