internal override ProcessStageResult ProcessStage(ProcessContext <TRunInfo> context, Action <CommandBase <TRunInfo> > resetContextFunc) { if (!context.ProgramArguments.HasMore()) { throw new ProcessException("Expected a sequence of arguments but reached the end of program args.", ProcessError.ExpectedProgramArgument, context.CommandLevel); } PropertyInfo propertyInfo = ReflectionHelper <TRunInfo> .GetPropertyInfoFromExpression(_listProperty); // initialize list if null var list = (IList <TListProperty>)propertyInfo.GetValue(context.RunInfo, null); if (list == null) { list = (IList <TListProperty>)Activator.CreateInstance(propertyInfo.PropertyType); propertyInfo.SetValue(context.RunInfo, list); } // Iterate over proceeding program args, adding parseable items to list. // Ends when all program args are exhausted or when an option or subcommand // has been identified. while (context.ProgramArguments.HasMore()) { if (context.ProgramArguments.NextIsOption()) { return(ProcessResult.Continue); } if (context.ProgramArguments.NextIsSubCommand()) { return(ProcessResult.Continue); } string next = context.ProgramArguments.Dequeue(); if (!context.Parser.TryParseAs(next, out TListProperty parsed)) { string message = _onParseErrorUseMessage != null ? _onParseErrorUseMessage(next) : $"Failed to process program argument '{next}' because it " + $"couldn't be parsed into a '{typeof(TListProperty).Name}'."; throw new ProcessException(message, ProcessError.ParserInvalidValue, context.CommandLevel); } ProcessStageResult result = _onParsed?.Invoke(parsed); if (result == ProcessResult.End) { return(ProcessResult.End); } list.Add(parsed); } return(ProcessResult.End); }
internal override ProcessStageResult ProcessStage(ProcessContext <TRunInfo> context, Action <CommandBase <TRunInfo> > resetContextFunc) { ProcessStageResult onMatchedResult = _onMatched?.Invoke(context.RunInfo); if (onMatchedResult == ProcessResult.End) { return(ProcessResult.End); } return(ProcessResult.Continue); }
internal TRunInfo Process() { TRunInfo runInfo = (TRunInfo)Activator.CreateInstance(typeof(TRunInfo)); ProcessContext <TRunInfo> context = new ProcessContext <TRunInfo>( runInfo, 0, _parser, _stages, _programArguments, _initialCommand, _globalOptions); Action <CommandBase <TRunInfo> > resetContextFunc = cmd => { context = context.RecreateForCommand(cmd); }; bool ended = false; while (_stages.Any()) { Stage <TRunInfo> current = _stages.Dequeue(); ProcessStageResult result = current.ProcessStage(context, resetContextFunc); switch (result) { case Continue _: break; case End _: ended = true; break; case null: default: throw new ProcessException( "Current stage processing returned an invalid result.", ProcessError.InvalidStageResult, context.CommandLevel); } if (ended) { break; } } return(runInfo); }
internal override ProcessStageResult ProcessStage(ProcessContext <TRunInfo> context, Action <CommandBase <TRunInfo> > resetContextFunc) { if (!context.ProgramArguments.HasMore()) { throw new ProcessException("Expected an argument but reached the end of program args.", ProcessError.ExpectedProgramArgument, context.CommandLevel); } string valueToken = context.ProgramArguments.Dequeue(); if (!context.Parser.HandlesType <TProperty>()) { throw new ProcessException($"Failed to process program argument '{valueToken}' because the " + $"parser cannot handle the property type of '{typeof(TProperty).Name}'.", ProcessError.ParserUnhandledType, context.CommandLevel); } if (!context.Parser.TryParseAs(valueToken, out TProperty parsed)) { string message = _onParseErrorUseMessage != null ? _onParseErrorUseMessage(valueToken) : $"Failed to process program argument '{valueToken}' because it " + $"couldn't be parsed into a '{typeof(TProperty).Name}'."; throw new ProcessException(message, ProcessError.ParserInvalidValue, context.CommandLevel); } ProcessStageResult result = _onParsed?.Invoke(parsed); if (result == ProcessResult.End) { return(ProcessResult.End); } PropertyInfo propertyInfo = ReflectionHelper <TRunInfo> .GetPropertyInfoFromExpression(_property); propertyInfo.SetValue(context.RunInfo, parsed); return(ProcessResult.Continue); }
private ProcessStageResult ProcessShort(char key, string valueString, ProcessContext <TRunInfo> context) { OptionProcessInfo <TRunInfo> processInfo = context.Options.GetOptionProcessInfo(key); object value = GetParsedValue(processInfo.Type, valueString, context, processInfo.OnParseErrorUseMessage); if (processInfo.OnParsed != null) { dynamic convertedType = Convert.ChangeType(value, processInfo.Type); dynamic onProcess = processInfo.OnParsed; ProcessStageResult onProcessResult = onProcess.Invoke(convertedType); if (onProcessResult == ProcessResult.End) { return(ProcessResult.End); } } processInfo.Setter(context.RunInfo, value); return(ProcessResult.Continue); }
public async Task ProcessAsync(TContext context) { OnPipelineProcessStart(context, _name); List <AsyncPipelineStage <TContext> > stages = GetStages(); foreach (var stage in stages) { if (await stage.ShouldSkipAsync(context)) { continue; } Guid stageId = OnStageProcessStart(context, stage.Name); ProcessStageResult result = await stage.ProcessAsync(context); bool endProcessing = false; switch (result) { case Continue _: break; case End _: endProcessing = true; break; default: throw new ArgumentOutOfRangeException($"'{result.GetType().Name}' is an invalid process stage result type."); } OnStageProcessEnd(stageId, context, stage.Name); if (endProcessing) { break; } } // //AsyncPipelineStage<TContext> currentStage = _head; //while (currentStage != null) //{ // if (await currentStage.ShouldSkipAsync(context)) // { // currentStage = currentStage.Next; // continue; // } // Guid stageId = OnStageProcessStart(context, currentStage.Name); // ProcessStageResult result = await currentStage.ProcessAsync(context); // bool endProcessing = false; // switch (result) // { // case Continue _: // break; // case End _: // endProcessing = true; // break; // default: // throw new ArgumentOutOfRangeException($"'{result.GetType().Name}' is an invalid process stage result type."); // } // OnStageProcessEnd(stageId, context, currentStage.Name); // if (endProcessing) // { // break; // } // currentStage = currentStage.Next; //} OnPipelineProcessEnd(context, _name); }