private (bool Exists, List <string> Values) GetValues(UriString uri) { if (uri.Query.TryGetValue(CommandArgumentQueryStringKeys.Position, out var p)) { var position = int.Parse((string)p); var elementAtOrDefault = _commandLine.AnonymousValues().ElementAtOrDefault(position); var exists = !(elementAtOrDefault is null); return ( exists, exists ? new List <string> { elementAtOrDefault } : new List <string>() ); } else { var names = uri.Path.Decoded.ToString().Split('/'); var id = new Identifier(names.Select(SoftString.Create)); return (_commandLine.Contains(id) ? (true, _commandLine[id].ToList()) : (false, new List <string>())); } }
//[NotNull, ItemNotNull] //public static IEnumerable<string> ArgumentValues([NotNull] this ICommandLine commandLine, int? position, Identifier id) //{ // if (commandLine == null) throw new ArgumentNullException(nameof(commandLine)); // return // position.HasValue // ? commandLine.AnonymousValues().Skip(position.Value).Take(1) // : commandLine[id]; //} //[ContractAnnotation("values: notnull")] public static bool TryGetArgumentValues([NotNull] this ICommandLine commandLine, Identifier id, int?position, [CanBeNull, ItemNotNull] out IList <string> values) { if (commandLine == null) { throw new ArgumentNullException(nameof(commandLine)); } if (commandLine.Contains(id)) { values = commandLine[id].ToList(); return(true); } if (position.HasValue && position.Value <= commandLine.AnonymousValues().Count() - 1) { values = new[] { commandLine.AnonymousValues().ElementAtOrDefault(position.Value) }; return(true); } values = default; return(false); }
public T Map <T>(T command, ICommandLine commandLine) where T : IConsoleCommand { if (command == null) { throw new ArgumentNullException(nameof(command)); } if (commandLine == null) { throw new ArgumentNullException(nameof(commandLine)); } // "Single" is fine because it's not possible to misconfigure the factory if commander-module is used so there is always a matching registration. var registration = _registrations.Single(r => r.CommandType == command.GetType()); IEnumerable <string> GetValues(CommandParameter parameter) { if (parameter.Metadata.Position > CommandLine.CommandIndex) { return(commandLine.Anonymous().Skip(parameter.Metadata.Position).Take(1)); } if (commandLine.Contains(parameter.Name)) { return(commandLine[parameter.Name]); } return(null); } foreach (var parameter in registration) { _logger.Trace($"Mapping parameter {parameter.Name}."); var values = GetValues(parameter)?.ToList(); // If parameter does not exist at all... if (values is null) { // ...check if it should exist. if (parameter.IsRequired) { throw ($"ArgumentNotFound{nameof(Exception)}", $"The required argument {parameter.Name} was not found.").ToDynamicException(); } if (parameter.DefaultValue.IsNotNull()) { parameter.SetValue(command, _converter.Convert(parameter.DefaultValue, parameter.Type)); } } else { if (parameter.Type == typeof(bool)) { var flag = values.SingleOrDefault(); // User did not specify any value but a flag alone. if (flag is null) { if (parameter.DefaultValue is bool defaultValue) { parameter.SetValue(command, !defaultValue); } else { // If DefaultValue is not set then the default is false. This negates it. parameter.SetValue(command, true); } } else { var value = _converter.Convert(flag, typeof(bool)); parameter.SetValue(command, value); } } else { // Parameter is required but not values are specified. This is an error. if (parameter.IsRequired && values.Empty()) { throw ($"ArgumentNotFound{nameof(Exception)}", $"The required argument {parameter.Name} was not found.").ToDynamicException(); } var convertible = parameter.Type.IsEnumerable(ignore: typeof(string)) ? (object)values : values.SingleOrDefault(); var value = _converter.Convert(convertible, parameter.Type); parameter.SetValue(command, value); } } } return(command); }