private static ParserResult <object> MatchVerb( Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer, IEnumerable <Tuple <Verb, Type> > verbs, IEnumerable <string> arguments, StringComparer nameComparer, CultureInfo parsingCulture) { return(verbs.Any(a => nameComparer.Equals(a.Item1.Name, arguments.First())) ? InstanceBuilder.Build( () => Activator.CreateInstance(verbs.Single(v => nameComparer.Equals(v.Item1.Name, arguments.First())).Item2), tokenizer, arguments.Skip(1), nameComparer, parsingCulture) : ParserResult.Create <object>( ParserResultType.Verbs, new NullInstance(), new[] { new BadVerbSelectedError(arguments.First()) }, Maybe.Just(verbs.Select(v => v.Item2)))); }
public void Explicit_help_request_generates_help_requested_error() { // Fixture setup var fakeOptions = new FakeOptions(); var expectedResult = ParserResult.Create( ParserResultType.Options, fakeOptions, new Error[] { new HelpRequestedError() }); // Exercize system var result = InstanceBuilder.Build( Maybe.Just <Func <FakeOptions> >(() => fakeOptions), new[] { "--help" }, StringComparer.Ordinal, CultureInfo.InvariantCulture); // Verify outcome Assert.True(expectedResult.Equals(result)); // Teardown }
public static ParserResult <object> Choose( Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer, IEnumerable <Type> types, IEnumerable <string> arguments, StringComparer nameComparer, CultureInfo parsingCulture) { var verbs = Verb.SelectFromTypes(types); return(arguments.Empty() ? ParserResult.Create <object>( ParserResultType.Verbs, new NullInstance(), new[] { new NoVerbSelectedError() }, Maybe.Just(types)) : nameComparer.Equals("help", arguments.First()) ? ParserResult.Create <object>( ParserResultType.Verbs, new NullInstance(), new[] { CreateHelpVerbRequestedError( verbs, arguments.Skip(1).SingleOrDefault() ?? string.Empty, nameComparer) }, Maybe.Just(types)) : MatchVerb(tokenizer, verbs, arguments, nameComparer, parsingCulture)); }
/// <summary> /// Creates a new instance of the <see cref="CommandLine.Text.HelpText"/> class, /// automatically handling verbs or options scenario. /// </summary> /// <param name='parserResult'>The <see cref="CommandLine.ParserResult{T}"/> containing the instance that collected command line arguments parsed with <see cref="CommandLine.Parser"/> class.</param> /// <returns> /// An instance of <see cref="CommandLine.Text.HelpText"/> class. /// </returns> /// <remarks>This feature is meant to be invoked automatically by the parser, setting the HelpWriter property /// of <see cref="CommandLine.ParserSettings"/>.</remarks> public static HelpText AutoBuild <T>(ParserResult <T> parserResult) { switch (parserResult.Tag) { case ParserResultType.Options: return(HelpText.AutoBuild(parserResult, current => HelpText.DefaultParsingErrorsHandler(parserResult, current))); case ParserResultType.Verbs: var helpVerbErr = parserResult.Errors.OfType <HelpVerbRequestedError>(); if (helpVerbErr.Any()) { var err = helpVerbErr.Single(); if (err.Matched) { var pr = ParserResult.Create(ParserResultType.Options, Activator.CreateInstance(err.Type), Enumerable.Empty <Error>()); return(HelpText.AutoBuild(pr, current => HelpText.DefaultParsingErrorsHandler(pr, current))); } } return(HelpText.AutoBuild(parserResult, current => HelpText.DefaultParsingErrorsHandler(parserResult, current), true)); default: throw new InvalidOperationException(); } }
public static ParserResult <T> Build <T>( Func <T> factory, Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer, IEnumerable <string> arguments, StringComparer nameComparer, CultureInfo parsingCulture) { var instance = factory(); if (arguments.Any() && nameComparer.Equals("--help", arguments.First())) { return(ParserResult.Create( ParserResultType.Options, instance, new[] { new HelpRequestedError() })); } var specProps = instance.GetType().GetSpecifications(pi => SpecificationProperty.Create( Specification.FromProperty(pi), pi, Maybe.Nothing <object>())); var optionSpecs = (from pt in specProps select pt.Specification) .ThrowingValidate(SpecificationGuards.Lookup) .OfType <OptionSpecification>(); var tokenizerResult = tokenizer(arguments, optionSpecs); var tokens = tokenizerResult.Value; var partitions = TokenPartitioner.Partition( tokens, name => TypeLookup.GetDescriptorInfo(name, optionSpecs, nameComparer)); var optionSpecProps = OptionMapper.MapValues( (from pt in specProps where pt.Specification.IsOption() select pt), partitions.Item1, (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture), nameComparer); var valueSpecProps = ValueMapper.MapValues( (from pt in specProps where pt.Specification.IsValue() select pt), partitions.Item2, (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture)); var missingValueErrors = from token in partitions.Item3 select new MissingValueOptionError( NameInfo.FromOptionSpecification(optionSpecs.Single(o => token.Text.MatchName(o.ShortName, o.LongName, nameComparer)))); var specPropsWithValue = optionSpecProps.Value.Concat(valueSpecProps.Value); instance = instance .SetProperties(specPropsWithValue, sp => sp.Value.IsJust(), sp => sp.Value.FromJust()) .SetProperties(specPropsWithValue, sp => sp.Value.IsNothing() && sp.Specification.DefaultValue.IsJust(), sp => sp.Specification.DefaultValue.FromJust()) .SetProperties(specPropsWithValue, sp => sp.Value.IsNothing() && sp.Specification.ConversionType.ToDescriptor() == DescriptorType.Sequence && sp.Specification.DefaultValue.MatchNothing(), sp => sp.Property.PropertyType.GetGenericArguments().Single().CreateEmptyArray()); var validationErrors = specPropsWithValue.Validate(SpecificationPropertyRules.Lookup) .OfType <Just <Error> >().Select(e => e.Value); return(ParserResult.Create( ParserResultType.Options, instance, tokenizerResult.Errors .Concat(missingValueErrors) .Concat(optionSpecProps.Errors) .Concat(valueSpecProps.Errors) .Concat(validationErrors))); }
public static ParserResult <T> Build <T>( Maybe <Func <T> > factory, Func <IEnumerable <string>, IEnumerable <OptionSpecification>, StatePair <IEnumerable <Token> > > tokenizer, IEnumerable <string> arguments, StringComparer nameComparer, CultureInfo parsingCulture) { var typeInfo = factory.Return(f => f().GetType(), typeof(T)); var specProps = typeInfo.GetSpecifications(pi => SpecificationProperty.Create( Specification.FromProperty(pi), pi, Maybe.Nothing <object>())); var specs = from pt in specProps select pt.Specification; var optionSpecs = specs .ThrowingValidate(SpecificationGuards.Lookup) .OfType <OptionSpecification>(); if (arguments.Any() && nameComparer.Equals("--help", arguments.First())) { return(ParserResult.Create( ParserResultType.Options, factory.Return(f => f(), default(T)), new[] { new HelpRequestedError() })); } var tokenizerResult = tokenizer(arguments, optionSpecs); var tokens = tokenizerResult.Value; var partitions = TokenPartitioner.Partition( tokens, name => TypeLookup.FindTypeDescriptorAndSibling(name, optionSpecs, nameComparer)); var optionSpecProps = OptionMapper.MapValues( (from pt in specProps where pt.Specification.IsOption() select pt), partitions.Options, (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture), nameComparer); var valueSpecProps = ValueMapper.MapValues( (from pt in specProps where pt.Specification.IsValue() select pt), partitions.Values, (vals, type, isScalar) => TypeConverter.ChangeType(vals, type, isScalar, parsingCulture)); var missingValueErrors = from token in partitions.Errors select new MissingValueOptionError( optionSpecs.Single(o => token.Text.MatchName(o.ShortName, o.LongName, nameComparer)).FromOptionSpecification()); var specPropsWithValue = optionSpecProps.Value.Concat(valueSpecProps.Value); T instance; if (ReflectionHelper.IsTypeMutable(typeInfo)) { instance = factory.Return(f => f(), Activator.CreateInstance <T>()); instance = instance .SetProperties(specPropsWithValue, sp => sp.Value.IsJust(), sp => sp.Value.FromJust()) .SetProperties(specPropsWithValue, sp => sp.Value.IsNothing() && sp.Specification.DefaultValue.IsJust(), sp => sp.Specification.DefaultValue.FromJust()) .SetProperties(specPropsWithValue, sp => sp.Value.IsNothing() && sp.Specification.TargetType == TargetType.Sequence && sp.Specification.DefaultValue.MatchNothing(), sp => sp.Property.PropertyType.GetGenericArguments().Single().CreateEmptyArray()); } else { var t = typeof(T); var ctor = t.GetConstructor((from p in specProps select p.Specification.ConversionType).ToArray()); var values = (from prms in ctor.GetParameters() join sp in specPropsWithValue on prms.Name.ToLower() equals sp.Property.Name.ToLower() select sp.Value.Return(v => v, sp.Specification.DefaultValue.Return(d => d, sp.Specification.ConversionType.CreateDefaultForImmutable()))).ToArray(); instance = (T)ctor.Invoke(values); } var validationErrors = specPropsWithValue.Validate( SpecificationPropertyRules.Lookup(tokens)); return(ParserResult.Create( ParserResultType.Options, instance, tokenizerResult.Errors .Concat(missingValueErrors) .Concat(optionSpecProps.Errors) .Concat(valueSpecProps.Errors) .Concat(validationErrors))); }