|
| 1 | +using System.Reflection; |
| 2 | +using RT.Internal; |
| 3 | +using RT.Util; |
| 4 | +using RT.Util.Consoles; |
| 5 | +using RT.Util.ExtensionMethods; |
| 6 | + |
| 7 | +namespace RT.CommandLine; |
| 8 | + |
| 9 | +static class CmdLineExtensions |
| 10 | +{ |
| 11 | + public static string[] GetOrderedOptionAttributeNames(this MemberInfo member) |
| 12 | + { |
| 13 | + var attr = member.GetCustomAttributes<OptionAttribute>().FirstOrDefault(); |
| 14 | + return attr == null ? null : attr.Names.OrderBy(compareOptionNames).ToArray(); |
| 15 | + } |
| 16 | + |
| 17 | + private static int compareOptionNames(string opt1, string opt2) |
| 18 | + { |
| 19 | + bool long1 = opt1.StartsWith("--"); |
| 20 | + bool long2 = opt2.StartsWith("--"); |
| 21 | + if (long1 == long2) |
| 22 | + return StringComparer.OrdinalIgnoreCase.Compare(opt1, opt2); |
| 23 | + else if (long1) |
| 24 | + return 1; // --blah comes after -blah |
| 25 | + else |
| 26 | + return -1; |
| 27 | + } |
| 28 | + |
| 29 | + public static ConsoleColoredString FormatParameterUsage(this FieldInfo field, bool isMandatory) |
| 30 | + { |
| 31 | + // Positionals |
| 32 | + if (field.IsDefined<IsPositionalAttribute>()) |
| 33 | + return (isMandatory ? "{0}" : "[{0}]").Color(CmdLineColor.OptionalityDelimiters).Fmt( |
| 34 | + "<".Color(CmdLineColor.FieldBrackets) + field.Name.Color(CmdLineColor.Field) + ">".Color(CmdLineColor.FieldBrackets)); |
| 35 | + |
| 36 | + // -t name [-t name [...]] — arrays, multi-value enums with CommandNames |
| 37 | + if (field.FieldType.IsArray || |
| 38 | + (field.FieldType.IsEnum && |
| 39 | + field.IsDefined<OptionAttribute>() && |
| 40 | + field.IsDefined<EnumOptionsAttribute>() && |
| 41 | + field.GetCustomAttributes<EnumOptionsAttribute>().First().Behavior == EnumBehavior.MultipleValues)) |
| 42 | + { |
| 43 | + return (isMandatory ? "{0} {1} [{0} {1} [...]]" : "[{0} {1} [{0} {1} [...]]]").Color(CmdLineColor.OptionalityDelimiters).Fmt( |
| 44 | + field.GetOrderedOptionAttributeNames().First().Color(CmdLineColor.Option), |
| 45 | + "<".Color(CmdLineColor.FieldBrackets) + field.Name.Color(CmdLineColor.Field) + ">".Color(CmdLineColor.FieldBrackets)); |
| 46 | + } |
| 47 | + |
| 48 | + // Enums with Option names |
| 49 | + if (field.FieldType.IsEnum && !field.IsDefined<OptionAttribute>()) |
| 50 | + { |
| 51 | + var options = field.FieldType.GetFields(BindingFlags.Public | BindingFlags.Static) |
| 52 | + .Where(fld => fld.IsDefined<OptionAttribute>() && !fld.IsDefined<UndocumentedAttribute>()) |
| 53 | + .Select(fi => fi.GetOrderedOptionAttributeNames().First().Color(CmdLineColor.Option)) |
| 54 | + .ToArray(); |
| 55 | + |
| 56 | + if (field.IsDefined<EnumOptionsAttribute>() && field.GetCustomAttributes<EnumOptionsAttribute>().First().Behavior == EnumBehavior.MultipleValues) |
| 57 | + // [-t] [-u] [-v] — multi-value enums with Option names |
| 58 | + return options.Select(opt => "[{0}]".Color(CmdLineColor.OptionalityDelimiters).Fmt(opt)).JoinColoredString(" "); |
| 59 | + |
| 60 | + // {-t|-u} — single-value enums with Options |
| 61 | + return (isMandatory ? (options.Length > 1 ? "{{{0}{1}" : "{0}") : "[{0}]").Color(CmdLineColor.OptionalityDelimiters).Fmt(options.JoinColoredString("|".Color(CmdLineColor.OptionalityDelimiters)), "}"); |
| 62 | + } |
| 63 | + |
| 64 | + // -t — bools |
| 65 | + if (field.FieldType == typeof(bool)) |
| 66 | + return "[{0}]".Color(CmdLineColor.OptionalityDelimiters).Fmt(field.GetOrderedOptionAttributeNames().First().Color(CmdLineColor.Option)); |
| 67 | + |
| 68 | + // -t name |
| 69 | + return (isMandatory ? "{0} {1}" : "[{0} {1}]").Color(CmdLineColor.OptionalityDelimiters).Fmt( |
| 70 | + field.GetOrderedOptionAttributeNames().First().Color(CmdLineColor.Option), |
| 71 | + "<".Color(CmdLineColor.FieldBrackets) + field.Name.Color(CmdLineColor.Field) + ">".Color(CmdLineColor.FieldBrackets)); |
| 72 | + } |
| 73 | +} |
0 commit comments