2020-12-07 12:33:24 -08:00
|
|
|
|
using System;
|
2017-02-02 13:22:06 -08:00
|
|
|
|
using System.Collections.Generic;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
using System.Linq;
|
2020-06-11 11:44:46 -07:00
|
|
|
|
|
2020-12-07 13:57:26 -08:00
|
|
|
|
namespace SabreTools.Help
|
2017-02-02 13:22:06 -08:00
|
|
|
|
{
|
2019-02-08 13:47:44 -08:00
|
|
|
|
public class Feature
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
#region Protected instance variables
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
2020-12-07 13:57:26 -08:00
|
|
|
|
protected ParameterType _featureType;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
protected bool _foundOnce = false;
|
|
|
|
|
|
protected object _value = null;
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Publicly facing variables
|
|
|
|
|
|
|
2020-06-10 22:37:19 -07:00
|
|
|
|
public string Name { get; protected set; }
|
|
|
|
|
|
public List<string> Flags { get; protected set; }
|
|
|
|
|
|
public string Description { get; protected set; }
|
2020-07-26 23:39:33 -07:00
|
|
|
|
public string LongDescription { get; protected set; }
|
2020-06-10 22:37:19 -07:00
|
|
|
|
public Dictionary<string, Feature> Features { get; protected set; }
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Constructors
|
|
|
|
|
|
|
|
|
|
|
|
public Feature()
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Name = null;
|
|
|
|
|
|
this.Flags = new List<string>();
|
|
|
|
|
|
this.Description = null;
|
|
|
|
|
|
this.LongDescription = null;
|
2020-12-07 13:57:26 -08:00
|
|
|
|
this._featureType = ParameterType.Flag;
|
2019-02-08 13:47:44 -08:00
|
|
|
|
this.Features = new Dictionary<string, Feature>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-07 13:57:26 -08:00
|
|
|
|
public Feature(string name, string flag, string description, ParameterType featureType, string longDescription = null)
|
2019-02-08 13:47:44 -08:00
|
|
|
|
{
|
|
|
|
|
|
this.Name = name;
|
2020-07-15 09:41:59 -07:00
|
|
|
|
this.Flags = new List<string>
|
|
|
|
|
|
{
|
|
|
|
|
|
flag
|
|
|
|
|
|
};
|
2019-02-08 13:47:44 -08:00
|
|
|
|
this.Description = description;
|
|
|
|
|
|
this.LongDescription = longDescription;
|
|
|
|
|
|
this._featureType = featureType;
|
|
|
|
|
|
this.Features = new Dictionary<string, Feature>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-07 13:57:26 -08:00
|
|
|
|
public Feature(string name, List<string> flags, string description, ParameterType featureType, string longDescription = null)
|
2019-02-08 13:47:44 -08:00
|
|
|
|
{
|
|
|
|
|
|
this.Name = name;
|
|
|
|
|
|
this.Flags = flags;
|
|
|
|
|
|
this.Description = description;
|
|
|
|
|
|
this.LongDescription = longDescription;
|
|
|
|
|
|
this._featureType = featureType;
|
|
|
|
|
|
this.Features = new Dictionary<string, Feature>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Accessors
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Directly address a given subfeature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Feature this[string name]
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
get { return this.Features.ContainsKey(name) ? this.Features[name] : null; }
|
2019-02-08 13:47:44 -08:00
|
|
|
|
set { this.Features[name] = value; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Directly address a given subfeature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Feature this[Feature subfeature]
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
get { return this.Features.ContainsKey(subfeature.Name) ? this.Features[subfeature.Name] : null; }
|
2019-02-08 13:47:44 -08:00
|
|
|
|
set { this.Features[subfeature.Name] = value; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Add a new feature for this feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="feature"></param>
|
|
|
|
|
|
public void AddFeature(Feature feature)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (this.Features == null)
|
|
|
|
|
|
this.Features = new Dictionary<string, Feature>();
|
|
|
|
|
|
|
2020-07-15 09:41:59 -07:00
|
|
|
|
lock (this.Features)
|
2019-02-08 13:47:44 -08:00
|
|
|
|
{
|
|
|
|
|
|
this.Features[feature.Name] = feature;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Add a new flag for this feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="flag">Flag to add for this feature</param>
|
|
|
|
|
|
public void AddFlag(string flag)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (this.Flags == null)
|
|
|
|
|
|
this.Flags = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
lock (this.Flags)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Flags.Add(flag);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Add a set of new flags for this feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="flags">List of flags to add to this feature</param>
|
|
|
|
|
|
public void AddFlags(List<string> flags)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (this.Flags == null)
|
|
|
|
|
|
this.Flags = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
lock (this.Flags)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Flags.AddRange(flags);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns if a flag exists for the current feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="name">Name of the flag to check</param>
|
|
|
|
|
|
/// <returns>True if the flag was found, false otherwise</returns>
|
|
|
|
|
|
public bool ContainsFlag(string name)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
return this.Flags.Any(f => f == name || f.TrimStart('-') == name);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns if the feature contains a flag that starts with the given character
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="c">Character to check against</param>
|
|
|
|
|
|
/// <returns>True if the flag was found, false otherwise</returns>
|
|
|
|
|
|
public bool StartsWith(char c)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
return this.Flags.Any(f => f.TrimStart('-').ToLowerInvariant()[0] == c);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Instance Methods
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Output this feature only
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="pre">Positive number representing number of spaces to put in front of the feature</param>
|
|
|
|
|
|
/// <param name="midpoint">Positive number representing the column where the description should start</param>
|
|
|
|
|
|
/// <param name="includeLongDescription">True if the long description should be formatted and output, false otherwise</param>
|
|
|
|
|
|
public List<string> Output(int pre = 0, int midpoint = 0, bool includeLongDescription = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Create the output list
|
|
|
|
|
|
List<string> outputList = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
// Build the output string first
|
2020-06-10 22:37:19 -07:00
|
|
|
|
string output = string.Empty;
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// Add the pre-space first
|
|
|
|
|
|
output += CreatePadding(pre);
|
|
|
|
|
|
|
|
|
|
|
|
// Preprocess the flags, if necessary
|
|
|
|
|
|
string[] newflags = new string[this.Flags.Count];
|
|
|
|
|
|
this.Flags.CopyTo(newflags);
|
|
|
|
|
|
switch (_featureType)
|
|
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.Int32:
|
|
|
|
|
|
case ParameterType.Int64:
|
|
|
|
|
|
case ParameterType.List:
|
|
|
|
|
|
case ParameterType.String:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
for (int i = 0; i < newflags.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
newflags[i] += "=";
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.Flag:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
default:
|
|
|
|
|
|
// No-op
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add all flags
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += string.Join(", ", newflags);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// If we have a midpoint set, check to see if the string needs padding
|
|
|
|
|
|
if (midpoint > 0 && output.Length < midpoint)
|
|
|
|
|
|
output += CreatePadding(midpoint - output.Length);
|
|
|
|
|
|
else
|
|
|
|
|
|
output += " ";
|
|
|
|
|
|
|
|
|
|
|
|
// Append the description
|
|
|
|
|
|
output += this.Description;
|
|
|
|
|
|
|
|
|
|
|
|
// Now append it to the list
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
|
|
|
|
|
|
// If we are outputting the long description, format it and then add it as well
|
|
|
|
|
|
if (includeLongDescription)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Get the width of the console for wrapping reference
|
|
|
|
|
|
int width = Console.WindowWidth - 1;
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare the output string
|
|
|
|
|
|
output = CreatePadding(pre + 4);
|
|
|
|
|
|
|
|
|
|
|
|
// Now split the input description and start processing
|
|
|
|
|
|
string[] split = this.LongDescription.Split(' ');
|
|
|
|
|
|
for (int i = 0; i < split.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we have a newline character, reset the line and continue
|
|
|
|
|
|
if (split[i].Contains("\n"))
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
string[] subsplit = split[i].Replace("\r", string.Empty).Split('\n');
|
2019-02-08 13:47:44 -08:00
|
|
|
|
for (int j = 0; j < subsplit.Length - 1; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Add the next word only if the total length doesn't go above the width of the screen
|
|
|
|
|
|
if (output.Length + subsplit[j].Length < width)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == pre + 4 ? string.Empty : " ") + subsplit[j];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
// Otherwise, we want to cache the line to output and create a new blank string
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
output = CreatePadding(pre + 4);
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == pre + 4 ? string.Empty : " ") + subsplit[j];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
output = CreatePadding(pre + 4);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-15 09:41:59 -07:00
|
|
|
|
output += subsplit[^1];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add the next word only if the total length doesn't go above the width of the screen
|
|
|
|
|
|
if (output.Length + split[i].Length < width)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == pre + 4 ? string.Empty : " ") + split[i];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
// Otherwise, we want to cache the line to output and create a new blank string
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
output = CreatePadding(pre + 4);
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == pre + 4 ? string.Empty : " ") + split[i];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add the last created output and a blank line for clarity
|
|
|
|
|
|
outputList.Add(output);
|
2020-06-10 22:37:19 -07:00
|
|
|
|
outputList.Add(string.Empty);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return outputList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create a padding space based on the given length
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="spaces">Number of padding spaces to add</param>
|
|
|
|
|
|
/// <returns>String with requested number of blank spaces</returns>
|
|
|
|
|
|
private string CreatePadding(int spaces)
|
|
|
|
|
|
{
|
2020-07-15 09:41:59 -07:00
|
|
|
|
return string.Empty.PadRight(spaces);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Output this feature and all subfeatures
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="tabLevel">Level of indentation for this feature</param>
|
|
|
|
|
|
/// <param name="pre">Positive number representing number of spaces to put in front of the feature</param>
|
|
|
|
|
|
/// <param name="midpoint">Positive number representing the column where the description should start</param>
|
|
|
|
|
|
/// <param name="includeLongDescription">True if the long description should be formatted and output, false otherwise</param>
|
|
|
|
|
|
public List<string> OutputRecursive(int tabLevel, int pre = 0, int midpoint = 0, bool includeLongDescription = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Create the output list
|
|
|
|
|
|
List<string> outputList = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
// Build the output string first
|
2020-06-10 22:37:19 -07:00
|
|
|
|
string output = string.Empty;
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// Normalize based on the tab level
|
|
|
|
|
|
int preAdjusted = pre;
|
|
|
|
|
|
int midpointAdjusted = midpoint;
|
|
|
|
|
|
if (tabLevel > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
preAdjusted += 4 * tabLevel;
|
|
|
|
|
|
midpointAdjusted += 4 * tabLevel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add the pre-space first
|
|
|
|
|
|
output += CreatePadding(preAdjusted);
|
|
|
|
|
|
|
|
|
|
|
|
// Preprocess the flags, if necessary
|
|
|
|
|
|
string[] newflags = new string[this.Flags.Count];
|
|
|
|
|
|
this.Flags.CopyTo(newflags);
|
|
|
|
|
|
switch (_featureType)
|
|
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.Int32:
|
|
|
|
|
|
case ParameterType.Int64:
|
|
|
|
|
|
case ParameterType.List:
|
|
|
|
|
|
case ParameterType.String:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
for (int i = 0; i < newflags.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
newflags[i] += "=";
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.Flag:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
default:
|
|
|
|
|
|
// No-op
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now add all flags
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += string.Join(", ", newflags);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// If we have a midpoint set, check to see if the string needs padding
|
|
|
|
|
|
if (midpoint > 0 && output.Length < midpointAdjusted)
|
|
|
|
|
|
output += CreatePadding(midpointAdjusted - output.Length);
|
|
|
|
|
|
else
|
|
|
|
|
|
output += " ";
|
|
|
|
|
|
|
|
|
|
|
|
// Append the description
|
|
|
|
|
|
output += this.Description;
|
|
|
|
|
|
|
|
|
|
|
|
// Now append it to the list
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
|
|
|
|
|
|
// If we are outputting the long description, format it and then add it as well
|
|
|
|
|
|
if (includeLongDescription)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Get the width of the console for wrapping reference
|
|
|
|
|
|
int width = Console.WindowWidth - 1;
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare the output string
|
|
|
|
|
|
output = CreatePadding(preAdjusted + 4);
|
|
|
|
|
|
|
|
|
|
|
|
// Now split the input description and start processing
|
|
|
|
|
|
string[] split = this.LongDescription.Split(' ');
|
|
|
|
|
|
for (int i = 0; i < split.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we have a newline character, reset the line and continue
|
|
|
|
|
|
if (split[i].Contains("\n"))
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
string[] subsplit = split[i].Replace("\r", string.Empty).Split('\n');
|
2019-02-08 13:47:44 -08:00
|
|
|
|
for (int j = 0; j < subsplit.Length - 1; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Add the next word only if the total length doesn't go above the width of the screen
|
|
|
|
|
|
if (output.Length + subsplit[j].Length < width)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == preAdjusted + 4 ? string.Empty : " ") + subsplit[j];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
// Otherwise, we want to cache the line to output and create a new blank string
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
output = CreatePadding(preAdjusted + 4);
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == preAdjusted + 4 ? string.Empty : " ") + subsplit[j];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
output = CreatePadding(preAdjusted + 4);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-15 09:41:59 -07:00
|
|
|
|
output += subsplit[^1];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add the next word only if the total length doesn't go above the width of the screen
|
|
|
|
|
|
if (output.Length + split[i].Length < width)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == preAdjusted + 4 ? string.Empty : " ") + split[i];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
// Otherwise, we want to cache the line to output and create a new blank string
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
outputList.Add(output);
|
|
|
|
|
|
output = CreatePadding(preAdjusted + 4);
|
2020-06-10 22:37:19 -07:00
|
|
|
|
output += (output.Length == preAdjusted + 4 ? string.Empty : " ") + split[i];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add the last created output and a blank line for clarity
|
|
|
|
|
|
outputList.Add(output);
|
2020-06-10 22:37:19 -07:00
|
|
|
|
outputList.Add(string.Empty);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Now let's append all subfeatures
|
|
|
|
|
|
foreach (string feature in this.Features.Keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
outputList.AddRange(this.Features[feature].OutputRecursive(tabLevel + 1, pre, midpoint, includeLongDescription));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return outputList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Validate whether a flag is valid for this feature or not
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input">Input to check against</param>
|
|
|
|
|
|
/// <param name="exact">True if just this feature should be checked, false if all subfeatures are checked as well</param>
|
|
|
|
|
|
/// <param name="ignore">True if the existing flag should be ignored, false otherwise</param>
|
|
|
|
|
|
/// <returns>True if the flag was valid, false otherwise</returns>
|
|
|
|
|
|
public bool ValidateInput(string input, bool exact = false, bool ignore = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool valid = false;
|
|
|
|
|
|
|
|
|
|
|
|
// Determine what we should be looking for
|
|
|
|
|
|
switch (_featureType)
|
|
|
|
|
|
{
|
|
|
|
|
|
// If we have a flag, make sure it doesn't have an equal sign in it
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.Flag:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
valid = !input.Contains("=") && this.Flags.Contains(input);
|
|
|
|
|
|
if (valid)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
_value = true;
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// If we've already found this feature before
|
|
|
|
|
|
if (_foundOnce && !ignore)
|
|
|
|
|
|
valid = false;
|
|
|
|
|
|
|
|
|
|
|
|
_foundOnce = true;
|
|
|
|
|
|
}
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
break;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
// If we have an Int32, try to parse it if at all possible
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.Int32:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
valid = input.Contains("=") && this.Flags.Contains(input.Split('=')[0]);
|
|
|
|
|
|
if (valid)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!Int32.TryParse(input.Split('=')[1], out int value))
|
|
|
|
|
|
value = Int32.MinValue;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
|
|
|
|
|
_value = value;
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// If we've already found this feature before
|
|
|
|
|
|
if (_foundOnce && !ignore)
|
|
|
|
|
|
valid = false;
|
|
|
|
|
|
|
|
|
|
|
|
_foundOnce = true;
|
|
|
|
|
|
}
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
break;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
// If we have an Int32, try to parse it if at all possible
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.Int64:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
valid = input.Contains("=") && this.Flags.Contains(input.Split('=')[0]);
|
|
|
|
|
|
if (valid)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!Int64.TryParse(input.Split('=')[1], out long value))
|
|
|
|
|
|
value = Int64.MinValue;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
|
|
|
|
|
_value = value;
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// If we've already found this feature before
|
|
|
|
|
|
if (_foundOnce && !ignore)
|
|
|
|
|
|
valid = false;
|
|
|
|
|
|
|
|
|
|
|
|
_foundOnce = true;
|
|
|
|
|
|
}
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
break;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
// If we have an input, make sure it has an equals sign in it
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.List:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
valid = input.Contains("=") && this.Flags.Contains(input.Split('=')[0]);
|
|
|
|
|
|
if (valid)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
if (_value == null)
|
|
|
|
|
|
_value = new List<string>();
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
2020-06-10 22:37:19 -07:00
|
|
|
|
(_value as List<string>).Add(input.Split('=')[1]);
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
break;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2020-12-07 13:57:26 -08:00
|
|
|
|
case ParameterType.String:
|
2019-02-08 13:47:44 -08:00
|
|
|
|
valid = input.Contains("=") && this.Flags.Contains(input.Split('=')[0]);
|
|
|
|
|
|
if (valid)
|
|
|
|
|
|
{
|
2020-06-10 22:37:19 -07:00
|
|
|
|
_value = input.Split('=')[1];
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
// If we've already found this feature before
|
|
|
|
|
|
if (_foundOnce && !ignore)
|
|
|
|
|
|
valid = false;
|
|
|
|
|
|
|
|
|
|
|
|
_foundOnce = true;
|
|
|
|
|
|
}
|
2020-06-10 22:37:19 -07:00
|
|
|
|
|
2019-02-08 13:47:44 -08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// If we haven't found a valid flag and we're not looking for just this feature, check to see if any of the subfeatures are valid
|
|
|
|
|
|
if (!valid && !exact)
|
2020-06-10 22:37:19 -07:00
|
|
|
|
valid = this.Features.Keys.Any(k => this.Features[k].ValidateInput(input));
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2020-06-10 22:37:19 -07:00
|
|
|
|
/// Get the boolean value associated with this feature
|
2019-02-08 13:47:44 -08:00
|
|
|
|
/// </summary>
|
2020-06-10 22:37:19 -07:00
|
|
|
|
public bool GetBoolValue()
|
2019-02-08 13:47:44 -08:00
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
if (_featureType != ParameterType.Flag)
|
2020-06-10 22:37:19 -07:00
|
|
|
|
throw new ArgumentException("Feature is not a flag");
|
2019-02-08 13:47:44 -08:00
|
|
|
|
|
2020-07-15 09:41:59 -07:00
|
|
|
|
return (_value as bool?) ?? false;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get the string value associated with this feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string GetStringValue()
|
|
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
if (_featureType != ParameterType.String)
|
2020-06-10 22:37:19 -07:00
|
|
|
|
throw new ArgumentException("Feature is not a string");
|
|
|
|
|
|
|
|
|
|
|
|
return (_value as string);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get the Int32 value associated with this feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int GetInt32Value()
|
|
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
if (_featureType != ParameterType.Int32)
|
2020-06-10 22:37:19 -07:00
|
|
|
|
throw new ArgumentException("Feature is not an int");
|
|
|
|
|
|
|
2020-07-15 09:41:59 -07:00
|
|
|
|
return (_value as int?) ?? int.MinValue;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get the Int64 value associated with this feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public long GetInt64Value()
|
|
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
if (_featureType != ParameterType.Int64)
|
2020-06-10 22:37:19 -07:00
|
|
|
|
throw new ArgumentException("Feature is not a long");
|
|
|
|
|
|
|
2020-07-15 09:41:59 -07:00
|
|
|
|
return (_value as long?) ?? long.MinValue;
|
2020-06-10 22:37:19 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Get the List\<string\> value associated with this feature
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public List<string> GetListValue()
|
|
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
if (_featureType != ParameterType.List)
|
2020-06-10 22:37:19 -07:00
|
|
|
|
throw new ArgumentException("Feature is not a list");
|
|
|
|
|
|
|
|
|
|
|
|
return (_value as List<string>) ?? new List<string>();
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns if this feature has a valid value or not
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>True if the feature is enabled, false otherwise</returns>
|
|
|
|
|
|
public bool IsEnabled()
|
|
|
|
|
|
{
|
2020-07-15 09:41:59 -07:00
|
|
|
|
return _featureType switch
|
|
|
|
|
|
{
|
2020-12-07 13:57:26 -08:00
|
|
|
|
ParameterType.Flag => (_value as bool?) == true,
|
|
|
|
|
|
ParameterType.String => (_value as string) != null,
|
|
|
|
|
|
ParameterType.Int32 => (_value as int?).HasValue && (_value as int?).Value != int.MinValue,
|
|
|
|
|
|
ParameterType.Int64 => (_value as long?).HasValue && (_value as long?).Value != long.MinValue,
|
|
|
|
|
|
ParameterType.List => (_value as List<string>) != null,
|
2020-07-15 09:41:59 -07:00
|
|
|
|
_ => false,
|
|
|
|
|
|
};
|
2019-02-08 13:47:44 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
2017-02-02 13:22:06 -08:00
|
|
|
|
}
|