Skip to content

Instantly share code, notes, and snippets.

@jchapuis
Last active February 20, 2020 11:35
Show Gist options
  • Save jchapuis/64b5adf9d0f3062e6a72dded110a6028 to your computer and use it in GitHub Desktop.
Save jchapuis/64b5adf9d0f3062e6a72dded110a6028 to your computer and use it in GitHub Desktop.
C# command-line parser
/// <summary>
/// Simple command line toggles parser:
/// - toggles are identified with (any number of) '-' prefixes
/// - toggle can be with or without associated value
/// - toggles are case-insensitive
///
/// <example>--toggle_without_value -toggle value</example>
/// </summary>
public class ToggleParser
{
private readonly Dictionary<string, string> toggles;
public ToggleParser(string[] args)
{
toggles =
args.Zip(args.Skip(1).Concat(new[] { string.Empty }), (first, second) => new { first, second })
.Where(pair => IsToggle(pair.first))
.ToDictionary(pair => RemovePrefix(pair.first).ToLowerInvariant(), g => IsToggle(g.second) ? string.Empty : g.second);
}
private static string RemovePrefix(string toggle)
{
return new string(toggle.SkipWhile(c => c == '-').ToArray());
}
private static bool IsToggle(string arg)
{
return arg.StartsWith("-", StringComparison.InvariantCulture);
}
public bool HasToggle(string toggle)
{
return toggles.ContainsKey(toggle.ToLowerInvariant());
}
public string GetToggleValueOrDefault(string toggle, string defaultValue)
{
string value;
return toggles.TryGetValue(toggle.ToLowerInvariant(), out value) ? value : defaultValue;
}
}
public class ToggleParserTest
{
public static IEnumerable<object[]> Arguments => new[]
{
new object[] { new[] {"-silent", "-session", "foobar"}, true, true, "foobar" },
new object[] { new[] {"-session", "foobar", "-silent"}, true, true, "foobar" },
new object[] { new[] {"-silent"}, true, false, string.Empty },
new object[] { new string[] {}, false, false, string.Empty },
new object[] { new[] {"--SeSSION", "foobar"}, false, true, "foobar" },
};
[Theory, MemberData(nameof(Arguments))]
internal void ToggleParser_ParsesToggles(string[] args, bool hasSilent, bool hasSession, string expectedSession)
{
// Act
var parser = new ToggleParser(args);
// Assert
parser.HasToggle("silent").Should().Be(hasSilent);
parser.HasToggle("session").Should().Be(hasSession);
parser.GetToggleValueOrDefault("session", string.Empty).Should().Be(expectedSession);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment