|
4 | 4 | using System.Linq; |
5 | 5 | using System.Reflection; |
6 | 6 | using Codeaddicts.libArgument.Attributes; |
| 7 | +using System.ComponentModel; |
7 | 8 |
|
8 | 9 | namespace Codeaddicts.libArgument |
9 | 10 | { |
| 11 | + /// <summary> |
| 12 | + /// Codeaddicts ArgumentParser |
| 13 | + /// </summary> |
10 | 14 | public static class ArgumentParser |
11 | 15 | { |
| 16 | + /// <summary> |
| 17 | + /// Parses the specified arguments. |
| 18 | + /// </summary> |
| 19 | + /// <param name="args">Arguments.</param> |
| 20 | + /// <typeparam name="T">The class that contains the options.</typeparam> |
12 | 21 | public static T Parse<T> (string[] args) where T : class, new() |
13 | 22 | { |
| 23 | + // Instantiate the class that contains the options |
14 | 24 | T options = new T (); |
| 25 | + |
| 26 | + // Create a new List<string> and fill it with the arguments |
15 | 27 | var list = new List<string> (args); |
| 28 | + |
| 29 | + // Get all public fields from the class instance |
16 | 30 | var fields = typeof (T).GetFields (BindingFlags.Instance | BindingFlags.Public); |
| 31 | + |
| 32 | + // Iterate over all fields |
17 | 33 | foreach (var item in fields) |
| 34 | + |
| 35 | + // Parse the current field |
18 | 36 | ParseField<T> (options, list, item.Name); |
| 37 | + |
| 38 | + // Return the generated class instance |
19 | 39 | return options; |
20 | 40 | } |
21 | 41 |
|
| 42 | + /// <summary> |
| 43 | + /// Generates and prints the argument doc. |
| 44 | + /// </summary> |
| 45 | + /// <typeparam name="T">The 1st type parameter.</typeparam> |
| 46 | + static void PrintHelp<T> () where T : class, new() |
| 47 | + { |
| 48 | + // Not ready yet. |
| 49 | + } |
| 50 | + |
| 51 | + /// <summary> |
| 52 | + /// Parses the field. |
| 53 | + /// </summary> |
| 54 | + /// <param name="options">Options.</param> |
| 55 | + /// <param name="args">Arguments.</param> |
| 56 | + /// <param name="name">Name.</param> |
| 57 | + /// <typeparam name="T">The 1st type parameter.</typeparam> |
22 | 58 | static void ParseField<T> (T options, List<string> args, string name) where T : class, new() |
23 | 59 | { |
| 60 | + // Get field |
24 | 61 | var field = typeof(T).GetField (name); |
| 62 | + |
| 63 | + // Get attributes |
25 | 64 | var attributes = field.GetCustomAttributes (true); |
26 | | - var cast = attributes.FirstOrDefault (attrib => attrib as CastAs != null) as CastAs ?? new CastAs (CastingType.String); |
| 65 | + |
| 66 | + // Iterate over the attributes |
27 | 67 | foreach (var attrib in attributes) { |
28 | | - if (attrib as Switch != null && (args.Contains ((attrib as Switch).FriendlyShort) || args.Contains ((attrib as Switch).FriendlyFull))) { |
29 | | - field.SetValue (options, true); |
30 | | - return; |
| 68 | + |
| 69 | + // Check if the current attribute is a Switch attribute |
| 70 | + var @switch = attrib as Switch; |
| 71 | + if (@switch != null) { |
| 72 | + |
| 73 | + // Check if the current attribute contains a valid parameter name |
| 74 | + if (args.Contains (@switch.FriendlyShort) || args.Contains (@switch.FriendlyFull)) { |
| 75 | + |
| 76 | + // Set value and return |
| 77 | + field.SetValue (options, true); |
| 78 | + return; |
| 79 | + } |
31 | 80 | } |
| 81 | + |
| 82 | + // Check if the current attribute is an Argument attribute |
32 | 83 | if (attrib as Argument == null) |
| 84 | + |
| 85 | + // Skip this iteration |
33 | 86 | continue; |
| 87 | + |
| 88 | + // Get the current attribute |
34 | 89 | var attribute = attrib as Argument; |
| 90 | + |
| 91 | + // Check if the arguments contain any of the valid parameter names |
35 | 92 | if (!(args.Contains (attribute.FriendlyShort) || args.Contains (attribute.FriendlyFull))) |
| 93 | + |
| 94 | + // Skip this iteration |
36 | 95 | continue; |
37 | | - var str = args.Contains (attribute.FriendlyShort) ? attribute.FriendlyShort : attribute.FriendlyFull; |
38 | | - var index = args.IndexOf (str) + 1; |
39 | | - var indexInRange = index <= args.Count - 1; |
40 | | - if (cast.Type != CastingType.Boolean && !indexInRange) |
41 | | - throw new ArgumentOutOfRangeException (string.Format ("Parameter of argument {0} out of range.", str)); |
42 | | - switch (cast.Type) { |
43 | | - case CastingType.String: |
44 | | - field.SetValue (options, args [index]); |
45 | | - return; |
46 | | - case CastingType.Boolean: |
47 | | - bool bool_result; |
48 | | - if (!Boolean.TryParse (args [index], out bool_result)) |
49 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to Boolean.", str)); |
50 | | - field.SetValue (options, bool_result); |
51 | | - return; |
52 | | - case CastingType.Object: |
53 | | - field.SetValue (options, args [index]); |
54 | | - return; |
55 | | - case CastingType.Int32: |
56 | | - int int32_result; |
57 | | - if (!Int32.TryParse (args [index], out int32_result)) |
58 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to Int32.", str)); |
59 | | - field.SetValue (options, int32_result); |
60 | | - return; |
61 | | - case CastingType.Int64: |
62 | | - long int64_result; |
63 | | - if (!Int64.TryParse (args [index], out int64_result)) |
64 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to Int64.", str)); |
65 | | - field.SetValue (options, int64_result); |
66 | | - return; |
67 | | - case CastingType.UInt32: |
68 | | - uint uint32_result; |
69 | | - if (!UInt32.TryParse (args [index], out uint32_result)) |
70 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to UInt32.", str)); |
71 | | - field.SetValue (options, uint32_result); |
72 | | - return; |
73 | | - case CastingType.UInt64: |
74 | | - ulong uint64_result; |
75 | | - if (!UInt64.TryParse (args [index], out uint64_result)) |
76 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to UInt64.", str)); |
77 | | - field.SetValue (options, uint64_result); |
78 | | - return; |
79 | | - case CastingType.Long: |
80 | | - long long_result; |
81 | | - if (!long.TryParse (args [index], out long_result)) |
82 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to long.", str)); |
83 | | - field.SetValue (options, long_result); |
84 | | - return; |
85 | | - case CastingType.ULong: |
86 | | - ulong ulong_result; |
87 | | - if (!ulong.TryParse (args [index], out ulong_result)) |
88 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to ulong.", str)); |
89 | | - field.SetValue (options, ulong_result); |
90 | | - return; |
91 | | - case CastingType.Float: |
92 | | - float float_result; |
93 | | - if (!float.TryParse (args [index], NumberStyles.Float, CultureInfo.InvariantCulture, out float_result)) |
94 | | - throw new InvalidCastException (string.Format ("Can't cast parameter of argument {0} to float.", str)); |
95 | | - field.SetValue (options, float_result); |
96 | | - return; |
| 96 | + |
| 97 | + // Get the parameter name |
| 98 | + var paramname = args.Contains (attribute.FriendlyShort) ? attribute.FriendlyShort : attribute.FriendlyFull; |
| 99 | + |
| 100 | + // Get the type of the field |
| 101 | + var type = field.FieldType; |
| 102 | + |
| 103 | + // Get the index of the current value |
| 104 | + var index = args.IndexOf (paramname) + 1; |
| 105 | + |
| 106 | + // Check if the index is in the range of our parameter count |
| 107 | + var indexInRange = index < args.Count; |
| 108 | + |
| 109 | + // Check if the index is in range of our parameter count |
| 110 | + if (!indexInRange) |
| 111 | + throw new ArgumentOutOfRangeException (string.Format ("Parameter of argument {0} is out of range.", paramname)); |
| 112 | + |
| 113 | + // Cast the string to the type of the field |
| 114 | + object value; |
| 115 | + try { |
| 116 | + value = TypeDescriptor.GetConverter (type).ConvertFromInvariantString (args [index]); |
| 117 | + } catch { |
| 118 | + throw new Exception (string.Format ("Cannot convert <string> to <{0}>.", type)); |
97 | 119 | } |
| 120 | + |
| 121 | + // Set the value of the field and return |
| 122 | + field.SetValue (options, value); |
98 | 123 | } |
99 | 124 | } |
100 | 125 | } |
|
0 commit comments