Exemplo n.º 1
0
 internal static void CheckRemainedOptions(CommandOptionsMetadata metadata, object options, IList<ParsingError> errors)
 {
     if (metadata.ValueListOption != null && !metadata.ValueListOption.IsProvided) errors.Add(new ParsingError(metadata.ValueListOption, ParsingErrorBase.IndexOutOfRange));
     foreach (var option in metadata.ValueOptions.Where(option => !option.IsProvided))
         errors.Add(new ParsingError(option, ParsingErrorBase.ValueMissed));
     foreach (var option in metadata.RequiredOptions.Where(option => !option.IsListOption && !option.IsProvided && option.HasDefaultValue))
     {
         option.Property.WriteValue(options, option.DefaultValue);
         option.IsProvided = true;
     }
     foreach (var option in metadata.RequiredOptions.Where(option => !option.IsProvided && !option.Required))
         option.IsProvided = true;
     foreach (var option in metadata.RequiredOptions.Where(option => !option.IsProvided))
         errors.Add(new ParsingError(option, ParsingErrorBase.OptionMissed));
 }
Exemplo n.º 2
0
 private static CommandOptionsMetadata GetOptionsMetadata(Type optionsType)
 {
     if (optionsType == null) return null;
     var optionsMetadata = new CommandOptionsMetadata(optionsType);
     foreach (var property in optionsType.GetProperties())
     {
         var attributes = property.GetCustomAttributes(typeof(OptionBaseAttribute), true).Cast<OptionBaseAttribute>().ToArray();
         Asserts.OperationNotAllowed(attributes.Length > 1, "More than one option attribute was declared on property {0}.".FormatFor(property.Name));
         var attribute = attributes.SingleOrDefault();
         if (attribute == null) continue;
         optionsMetadata.Add(GetOptionMetadata(property, attribute));
     }
     return optionsMetadata;
 }
Exemplo n.º 3
0
 internal static ParsingResult Parse(CommandOptionsMetadata metadata, object options, string[] args)
 {
     metadata.Reset();
     var errors = new List<ParsingError>();
     if (args != null && args.Any())
     {
         var argsEnumerator = new TwoWayEnumerator<string>(args);
         var valueIndex = 0;
         var valueList = new List<string>();
         while (argsEnumerator.MoveNext())
         {
             var currentArg = argsEnumerator.Current;
             if (IsShortOption(currentArg))
             {
                 #region short option
                 var value = currentArg.Substring(1);
                 if (value.IsNullOrEmptyOrWhiteSpace())
                 {
                     errors.Add(new ParsingError(null, ParsingErrorBase.InvalidValue) { Value = currentArg });
                     continue;
                 }
                 var groupEnumerator = new TwoWayEnumerator<char>(value);
                 while (groupEnumerator.MoveNext())
                 {
                     var currentChar = groupEnumerator.Current;
                     var optionMetadata = metadata[currentChar];
                     if (optionMetadata == null)
                     {
                         errors.Add(new ParsingError(null, ParsingErrorBase.UnboundValue) { Value = currentChar.ToString(CultureInfo.InvariantCulture) });
                         continue;
                     }
                     if (optionMetadata.IsProvided)
                     {
                         errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.RedundantOption));
                         continue;
                     }
                     optionMetadata.IsProvided = true;
                     if (optionMetadata.IsSwitchOption)
                     {
                         optionMetadata.Property.WriteValue(options, true);
                         continue;
                     }
                     if (!groupEnumerator.IsLast || argsEnumerator.IsLast || !argsEnumerator.MoveNext() || !IsValue(argsEnumerator.Current))
                     {
                         errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.ValueMissed));
                         continue;
                     }
                     if (optionMetadata.IsOption && optionMetadata.IsListOption)
                     {
                         var argumentType = !optionMetadata.Type.IsArray ? optionMetadata.Type.GetGenericArguments().Single() : optionMetadata.Type.GetElementType();
                         var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(argumentType));
                         var values = argsEnumerator.Current.Split(new[] { ((CommandOptionListOptionMetadata)optionMetadata).Separator },
                                         StringSplitOptions.RemoveEmptyEntries);
                         var proceed = true;
                         foreach (var splittedValue in values)
                         {
                             object convertedValue;
                             if (!Converter.ConvertFromString(argumentType, splittedValue, out convertedValue) && !Validator.IsValid(optionMetadata.Validators, convertedValue))
                             {
                                 errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.InvalidValue) { Value = argsEnumerator.Current });
                                 proceed = false;
                                 break;
                             }
                             list.Add(convertedValue);
                         }
                         if (!proceed) continue;
                         if (optionMetadata.Type.IsArray)
                         {
                             var array = Array.CreateInstance(argumentType, list.Count);
                             list.CopyTo(array, 0);
                             optionMetadata.Property.WriteValue(options, array);
                         }
                         else optionMetadata.Property.WriteValue(options, list);
                         continue;
                     }
                     // simple option left
                     if (!optionMetadata.Property.WriteValue(options, argsEnumerator.Current))
                         errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.InvalidValue) { Value = argsEnumerator.Current });
                 }
                 #endregion
             }
             else if (IsLongOption(currentArg)) // long option
             {
                 #region long option
                 var value = currentArg.Substring(2);
                 if (value.IsNullOrEmptyOrWhiteSpace())
                 {
                     errors.Add(new ParsingError(null, ParsingErrorBase.InvalidValue) { Value = currentArg });
                     continue;
                 }
                 var optionMetadata = metadata[value];
                 if (optionMetadata == null)
                 {
                     errors.Add(new ParsingError(null, ParsingErrorBase.UnboundValue) { Value = value });
                     continue;
                 }
                 if (optionMetadata.IsProvided)
                 {
                     errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.RedundantOption));
                     continue;
                 }
                 optionMetadata.IsProvided = true;
                 if (optionMetadata.IsSwitchOption)
                 {
                     optionMetadata.Property.WriteValue(options, true);
                     continue;
                 }
                 if (!argsEnumerator.MoveNext() || !IsValue(argsEnumerator.Current))
                 {
                     errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.ValueMissed));
                     continue;
                 }
                 if (optionMetadata.IsOption && optionMetadata.IsListOption)
                 {
                     var argumentType = !optionMetadata.Type.IsArray ? optionMetadata.Type.GetGenericArguments().Single() : optionMetadata.Type.GetElementType();
                     var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(argumentType));
                     var values = argsEnumerator.Current.Split(new[] { ((CommandOptionListOptionMetadata)optionMetadata).Separator },
                                     StringSplitOptions.RemoveEmptyEntries);
                     var proceed = true;
                     foreach (var splittedValue in values)
                     {
                         object convertedValue;
                         if (!Converter.ConvertFromString(argumentType, splittedValue, out convertedValue) && !Validator.IsValid(optionMetadata.Validators, convertedValue))
                         {
                             errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.InvalidValue) { Value = argsEnumerator.Current });
                             proceed = false;
                             break;
                         }
                         list.Add(convertedValue);
                     }
                     if (!proceed) continue;
                     if (optionMetadata.Type.IsArray)
                     {
                         var array = Array.CreateInstance(argumentType, list.Count);
                         list.CopyTo(array, 0);
                         optionMetadata.Property.WriteValue(options, array);
                     }
                     else optionMetadata.Property.WriteValue(options, list);
                     continue;
                 }
                 // simple option left
                 if (!optionMetadata.Property.WriteValue(options, argsEnumerator.Current))
                     errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.InvalidValue) { Value = argsEnumerator.Current });
                 #endregion
             }
             else
             {
                 #region values
                 var optionMetadata = metadata[valueIndex++];
                 if (optionMetadata != null)
                 {
                     optionMetadata.IsProvided = true;
                     if (!optionMetadata.Property.WriteValue(options, argsEnumerator.Current))
                         errors.Add(new ParsingError(optionMetadata, ParsingErrorBase.InvalidValue) { Value = argsEnumerator.Current });
                     continue;
                 }
                 valueList.Add(argsEnumerator.Current);
                 #endregion
             }
         }
         if (valueList.Any() && metadata.ValueListOption == null)
             errors.Add(new ParsingError(null, ParsingErrorBase.UnboundValue) { Value = string.Join(",", valueList) });
         else if (valueList.Any())
         {
             var argumentType = !metadata.ValueListOption.Type.IsArray ? metadata.ValueListOption.Type.GetGenericArguments().Single() : metadata.ValueListOption.Type.GetElementType();
             var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(argumentType));
             var proceed = true;
             foreach (var item in valueList)
             {
                 object convertedValue;
                 if (!Converter.ConvertFromString(argumentType, item, out convertedValue) && !Validator.IsValid(metadata.ValueListOption.Validators, convertedValue))
                 {
                     errors.Add(new ParsingError(metadata.ValueListOption, ParsingErrorBase.InvalidValue) { Value = item });
                     proceed = false;
                     break;
                 }
                 list.Add(convertedValue);
                 metadata.ValueListOption.ElementsCount++;
             }
             if (proceed)
             {
                 if (metadata.ValueListOption.Type.IsArray)
                 {
                     var array = Array.CreateInstance(argumentType, list.Count);
                     list.CopyTo(array, 0);
                     metadata.ValueListOption.Property.WriteValue(options, array);
                 }
                 else metadata.ValueListOption.Property.WriteValue(options, list);
             }
         }
     }
     CheckRemainedOptions(metadata, options, errors);
     return new ParsingResult(errors);
 }