1- using System . Diagnostics ;
1+ using System . Diagnostics ;
2+ using System . Numerics ;
23using System . Reflection ;
34using RT . Internal ;
45using RT . PostBuild ;
@@ -203,6 +204,10 @@ public static ConsoleColoredString GenerateHelp<TArgs>(int? wrapWidth = null, Ty
203204 return getHelpGenerator ( subType ?? typeof ( TArgs ) , helpProcessor ) ( wrapWidth ?? ConsoleUtil . WrapToWidth ( ) ) ;
204205 }
205206
207+ private static bool isIntegerType ( Type type ) => Type . GetTypeCode ( type ) is TypeCode . Byte or TypeCode . SByte or TypeCode . Int16 or TypeCode . Int32 or TypeCode . Int64 or TypeCode . UInt16 or TypeCode . UInt32 or TypeCode . UInt64 or TypeCode . Boolean or TypeCode . Char or TypeCode . DateTime ;
208+ private static bool isTrueIntegerType ( Type type ) => Type . GetTypeCode ( type ) is TypeCode . Byte or TypeCode . SByte or TypeCode . Int16 or TypeCode . Int32 or TypeCode . Int64 or TypeCode . UInt16 or TypeCode . UInt32 or TypeCode . UInt64 ;
209+ private static bool isTrueIntegerNullableType ( Type type ) => type . IsConstructedGenericType && type . GetGenericTypeDefinition ( ) == typeof ( Nullable < > ) && isTrueIntegerType ( type . GetGenericArguments ( ) [ 0 ] ) ;
210+
206211 private static object parseCommandLine ( string [ ] args , Type type , int i , Func < ConsoleColoredString , ConsoleColoredString > helpProcessor )
207212 {
208213 if ( i < args . Length )
@@ -346,7 +351,7 @@ private static object parseCommandLine(string[] args, Type type, int i, Func<Con
346351 options [ o ] = ( ) => { field . SetValue ( ret , true ) ; i ++ ; missingMandatories . Remove ( field ) ; } ;
347352 }
348353 // ### STRING and INTEGER fields (including nullable)
349- else if ( field . FieldType == typeof ( string ) || ExactConvert . IsTrueIntegerType ( field . FieldType ) || ExactConvert . IsTrueIntegerNullableType ( field . FieldType ) ||
354+ else if ( field . FieldType == typeof ( string ) || isTrueIntegerType ( field . FieldType ) || isTrueIntegerNullableType ( field . FieldType ) ||
350355 field . FieldType == typeof ( float ) || field . FieldType == typeof ( float ? ) || field . FieldType == typeof ( double ) || field . FieldType == typeof ( double ? ) )
351356 {
352357 if ( positional is double order )
@@ -526,6 +531,41 @@ private static object parseCommandLine(string[] args, Type type, int i, Func<Con
526531
527532 private static IEnumerable < Type > allTypes ( ) => AppDomain . CurrentDomain . GetAssemblies ( ) . SelectMany ( asm => asm . GetTypes ( ) ) ;
528533
534+ private static bool tryConvert ( Type toType , string value , out object result )
535+ {
536+ if ( toType . IsEnum )
537+ {
538+ object [ ] parameters = [ value , null ] ;
539+ var succeeded = ( bool ) typeof ( Enum ) . GetMethods ( BindingFlags . Static | BindingFlags . Public ) . First ( m => m . Name == "TryParse" && m . GetParameters ( ) . Length == 2 ) . MakeGenericMethod ( toType ) . Invoke ( null , parameters ) ;
540+ result = parameters [ 1 ] ;
541+ return succeeded ;
542+ }
543+
544+ bool success = false ;
545+ object converted = null ;
546+ switch ( Type . GetTypeCode ( toType ) )
547+ {
548+ case TypeCode . Boolean : { success = bool . TryParse ( value , out bool temp ) ; converted = temp ; break ; }
549+ case TypeCode . Byte : { success = byte . TryParse ( value , out byte temp ) ; converted = temp ; break ; }
550+ case TypeCode . SByte : { success = sbyte . TryParse ( value , out sbyte temp ) ; converted = temp ; break ; }
551+ case TypeCode . Int16 : { success = short . TryParse ( value , out short temp ) ; converted = temp ; break ; }
552+ case TypeCode . UInt16 : { success = ushort . TryParse ( value , out ushort temp ) ; converted = temp ; break ; }
553+ case TypeCode . Int32 : { success = int . TryParse ( value , out int temp ) ; converted = temp ; break ; }
554+ case TypeCode . UInt32 : { success = uint . TryParse ( value , out uint temp ) ; converted = temp ; break ; }
555+ case TypeCode . Int64 : { success = long . TryParse ( value , out long temp ) ; converted = temp ; break ; }
556+ case TypeCode . UInt64 : { success = ulong . TryParse ( value , out ulong temp ) ; converted = temp ; break ; }
557+ case TypeCode . Single : { success = float . TryParse ( value , out float temp ) ; converted = temp ; break ; }
558+ case TypeCode . Double : { success = double . TryParse ( value , out double temp ) ; converted = temp ; break ; }
559+ case TypeCode . Decimal : { success = decimal . TryParse ( value , out decimal temp ) ; converted = temp ; break ; }
560+ case TypeCode . DateTime : { success = DateTime . TryParse ( value , out DateTime temp ) ; converted = temp ; break ; }
561+ case TypeCode . Char : { success = char . TryParse ( value , out char temp ) ; converted = temp ; break ; }
562+ case TypeCode . String : { converted = value ; success = true ; break ; }
563+ case TypeCode . Object when toType == typeof ( BigInteger ) : { success = BigInteger . TryParse ( value , out BigInteger temp ) ; converted = temp ; break ; }
564+ }
565+ result = success ? converted : null ;
566+ return success ;
567+ }
568+
529569 private static bool convertStringAndSetField ( string value , object cmdLineObject , FieldInfo field )
530570 {
531571 object result ;
@@ -534,10 +574,10 @@ private static bool convertStringAndSetField(string value, object cmdLineObject,
534574 result = value ;
535575 else
536576 {
537- Type type = field . FieldType . IsGenericType && field . FieldType . GetGenericTypeDefinition ( ) == typeof ( Nullable < > )
577+ Type type = field . FieldType . IsConstructedGenericType && field . FieldType . GetGenericTypeDefinition ( ) == typeof ( Nullable < > )
538578 ? field . FieldType . GetGenericArguments ( ) [ 0 ]
539579 : field . FieldType ;
540- if ( ! ExactConvert . Try ( type , value , out result ) )
580+ if ( ! tryConvert ( type , value , out result ) )
541581 return false ;
542582 }
543583 field . SetValue ( cmdLineObject , result ) ;
@@ -908,8 +948,8 @@ private static void postBuildStep(IPostBuildReporter rep, Type commandLineType,
908948 }
909949 // ### STRING, STRING[], INTEGER and FLOATING fields (including nullable)
910950 else if ( field . FieldType == typeof ( string ) || field . FieldType == typeof ( string [ ] ) ||
911- ( ExactConvert . IsTrueIntegerType ( field . FieldType ) && ! field . FieldType . IsEnum ) ||
912- ( ExactConvert . IsTrueIntegerNullableType ( field . FieldType ) && ! field . FieldType . GetGenericArguments ( ) [ 0 ] . IsEnum ) ||
951+ ( isTrueIntegerType ( field . FieldType ) && ! field . FieldType . IsEnum ) ||
952+ ( isTrueIntegerNullableType ( field . FieldType ) && ! field . FieldType . GetGenericArguments ( ) [ 0 ] . IsEnum ) ||
913953 field . FieldType == typeof ( float ) || field . FieldType == typeof ( float ? ) || field . FieldType == typeof ( double ) || field . FieldType == typeof ( double ? ) )
914954 {
915955 // options is null if and only if this field is positional
0 commit comments