forked from natemcmaster/CommandLineUtils
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce mapped options as defined in natemcmaster#334
- Loading branch information
1 parent
fbc8668
commit 912b155
Showing
22 changed files
with
1,139 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright (c) Nate McMaster. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Reflection; | ||
|
||
namespace McMaster.Extensions.CommandLineUtils.Attributes | ||
{ | ||
/// <summary> | ||
/// Represents one or many command line option that is identified by flag proceeded by '-' or '--'. | ||
/// Options are not positional. Compare to <see cref="ArgumentAttribute"/>. | ||
/// </summary> | ||
[AttributeUsage(AttributeTargets.Property)] | ||
public sealed class MappedOptionAttribute : OptionAttributeBase | ||
{ | ||
/// <summary> | ||
/// Initializes a new <see cref="MappedOptionAttribute"/>. | ||
/// </summary> | ||
public MappedOptionAttribute(object constantValue) | ||
{ | ||
ConstantValue = constantValue; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new <see cref="MappedOptionAttribute"/>. | ||
/// </summary> | ||
/// <param name="template">The string template. This is parsed into <see cref="CommandOption.ShortName"/> and <see cref="CommandOption.LongName"/>.</param> | ||
/// <param name="constantValue">The value to assign the the option is given.</param> | ||
public MappedOptionAttribute(string template, object constantValue) | ||
{ | ||
Template = template; | ||
ConstantValue = constantValue; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new <see cref="MappedOptionAttribute"/>. | ||
/// </summary> | ||
/// <param name="template">The template</param> | ||
/// <param name="description">The option description</param> | ||
/// <param name="constantValue">The value to assign the the option is given.</param> | ||
public MappedOptionAttribute(string template, string? description, object constantValue) | ||
{ | ||
Template = template; | ||
Description = description; | ||
ConstantValue = constantValue; | ||
} | ||
|
||
/// <summary> | ||
/// Defines the type of the option. When not set, this will be inferred from the CLR type of the property. | ||
/// </summary> | ||
/// <seealso cref="CommandOption.OptionType"/> | ||
public CommandOptionType? OptionType { get; set; } | ||
|
||
/// <summary> | ||
/// Defines the value assigned to the property when the option is given. | ||
/// </summary> | ||
/// <seealso cref="ConstantValueOption{T}.ConstantValue"/> | ||
public object? ConstantValue { get; set; } | ||
|
||
internal CommandOption Configure<T>(MappedOption<T> mappedOption, PropertyInfo prop) | ||
{ | ||
T constantValue; | ||
try | ||
{ | ||
constantValue = (T)ConstantValue!; | ||
} | ||
catch (InvalidCastException e) | ||
{ | ||
throw new InvalidOperationException(Strings.CannotDetermineOptionType(prop), e); | ||
} | ||
ConstantValueOption<T> option; | ||
if (Template != null) | ||
{ | ||
option = mappedOption.Add(Template, constantValue); | ||
} | ||
else | ||
{ | ||
option = mappedOption.Add(constantValue); | ||
var stringValue = constantValue?.ToString().ToKebabCase(); | ||
if (stringValue != null) | ||
{ | ||
option.LongName = stringValue; | ||
option.ShortName = stringValue.Substring(0, 1); | ||
} | ||
} | ||
|
||
Configure(option); | ||
return option; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copyright (c) Nate McMaster. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.Linq; | ||
|
||
namespace McMaster.Extensions.CommandLineUtils | ||
{ | ||
/// <summary> | ||
/// An option that returns a constant <see cref="ParsedValue"/> when specified on the command-line | ||
/// </summary> | ||
/// <typeparam name="T">type of <see cref="ConstantValue"/></typeparam> | ||
public class ConstantValueOption<T> : CommandOption, IOption<T>, IInternalCommandParamOfT | ||
{ | ||
private readonly List<T> _parsedValues = new List<T>(); | ||
private readonly T _constantValue; | ||
private bool _hasBeenParsed; | ||
|
||
/// <summary> | ||
/// Initializes a new <see cref="ConstantValueOption{T}"/> | ||
/// </summary> | ||
/// <param name="template">The option template.</param> | ||
/// <param name="constantValue">The value to return is specified on the command line</param> | ||
/// <see cref="MappedOption{T}"/> | ||
public ConstantValueOption(string template, T constantValue) : base(template, CommandOptionType.NoValue) | ||
{ | ||
_constantValue = constantValue; | ||
UnderlyingType = typeof(T); | ||
} | ||
|
||
internal ConstantValueOption(T constantValue) : base(CommandOptionType.NoValue) | ||
{ | ||
_constantValue = constantValue; | ||
UnderlyingType = typeof(T); | ||
} | ||
|
||
/// <summary> | ||
/// The value that is returned for any usage of this option | ||
/// </summary> | ||
public T ConstantValue => _constantValue; | ||
|
||
/// <summary> | ||
/// The parsed value. | ||
/// </summary> | ||
public T ParsedValue => ParsedValues.FirstOrDefault(); | ||
|
||
/// <summary> | ||
/// All parsed values; | ||
/// </summary> | ||
public IReadOnlyList<T> ParsedValues | ||
{ | ||
get | ||
{ | ||
if (!_hasBeenParsed) | ||
{ | ||
((IInternalCommandParamOfT)this).Parse(CultureInfo.CurrentCulture); | ||
} | ||
|
||
return _parsedValues; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// "Parse" the user-given values into the constant value | ||
/// </summary> | ||
void IInternalCommandParamOfT.Parse(CultureInfo culture) | ||
{ | ||
_hasBeenParsed = true; | ||
_parsedValues.Clear(); | ||
foreach (var t in base._values) | ||
{ | ||
_parsedValues.Add(_constantValue); | ||
} | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void Reset() | ||
{ | ||
_hasBeenParsed = false; | ||
_parsedValues.Clear(); | ||
base.Reset(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.