Skip to content

Commit 0baf8d7

Browse files
committed
WIP ArgumentManager
1 parent 4311f72 commit 0baf8d7

10 files changed

Lines changed: 97 additions & 24 deletions

File tree

CommandLineParser.Tests/OptionBuilderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class OptionBuilderTest
1616
public void OptionBuilderConfiguresOptionCorrectly()
1717
{
1818
var resolverMock = new Mock<ICommandLineArgumentResolver<string>>();
19-
var option = new CommandLineArgumentOption<object, string>(new object(), o => o.ToString(), resolverMock.Object);
19+
var option = new CommandLineOption<object, string>(new object(), o => o.ToString(), resolverMock.Object);
2020
var builder = option as IOptionBuilder<string>;
2121

2222
string sDefault = "default";

CommandLineParser/Abstractions/Command/ICommandLineCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ public interface ICommandLineCommand
1313
bool IsRequired { get; }
1414
bool HasShortName { get; }
1515
bool HasLongName { get; }
16+
bool HasDefault { get; }
1617
}
1718
}
Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
using System;
1+
using MatthiWare.CommandLine.Abstractions.Command;
2+
using System;
23
using System.Collections.Generic;
34
using System.Text;
45

56
namespace MatthiWare.CommandLine.Abstractions
67
{
7-
public interface ICommandLineOption
8+
public interface ICommandLineOption : ICommandLineCommand
89
{
9-
string ShortName { get; }
10-
string LongName { get; }
11-
string HelpText { get; }
12-
bool IsRequired { get; }
13-
bool HasDefault { get; }
14-
bool HasShortName { get; }
15-
bool HasLongName { get; }
10+
1611
}
1712
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using MatthiWare.CommandLine.Abstractions.Command;
2+
using MatthiWare.CommandLine.Abstractions.Models;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Text;
6+
7+
namespace MatthiWare.CommandLine.Abstractions.Parsing
8+
{
9+
public interface IArgumentGrouper
10+
{
11+
bool TryGetValue(ICommandLineOption cmd, out string value);
12+
}
13+
}

CommandLineParser/CommandLineParser.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace MatthiWare.CommandLine
1919
public sealed class CommandLineParser<TSource> : ICommandLineParser<TSource> where TSource : class, new()
2020
{
2121
private readonly TSource m_option;
22-
private readonly List<CommandLineArgumentOptionBase> m_options;
22+
private readonly List<CommandLineOptionBase> m_options;
2323
private readonly List<CommandLineCommandBase> m_commands;
2424

2525
public IReadOnlyList<ICommandLineOption> Options => m_options.AsReadOnly();
@@ -32,7 +32,7 @@ public CommandLineParser()
3232
{
3333
m_option = new TSource();
3434

35-
m_options = new List<CommandLineArgumentOptionBase>();
35+
m_options = new List<CommandLineOptionBase>();
3636
m_commands = new List<CommandLineCommandBase>();
3737

3838
ResolverFactory = new ResolverFactory();
@@ -43,7 +43,7 @@ public IOptionBuilder<TProperty> Configure<TProperty>(Expression<Func<TSource, T
4343

4444
private IOptionBuilder<TProperty> ConfigureInternal<TProperty>(Expression<Func<TSource, TProperty>> selector)
4545
{
46-
var option = new CommandLineArgumentOption<TSource, TProperty>(m_option, selector, ResolverFactory.CreateResolver<TProperty>());
46+
var option = new CommandLineOption<TSource, TProperty>(m_option, selector, ResolverFactory.CreateResolver<TProperty>());
4747

4848
m_options.Add(option);
4949

@@ -59,9 +59,7 @@ public IParserResult<TSource> Parse(string[] args)
5959

6060
foreach (var cmd in m_commands)
6161
{
62-
int idx = lstArgs.FindIndex(arg =>
63-
(cmd.HasShortName && string.Equals(cmd.ShortName, arg, StringComparison.InvariantCultureIgnoreCase)) ||
64-
(cmd.HasLongName && string.Equals(cmd.LongName, arg, StringComparison.InvariantCultureIgnoreCase)));
62+
6563

6664
if (idx < 0 || idx > lstArgs.Count)
6765
{
@@ -81,9 +79,7 @@ public IParserResult<TSource> Parse(string[] args)
8179

8280
foreach (var option in m_options)
8381
{
84-
int idx = lstArgs.FindIndex(arg =>
85-
(option.HasShortName && string.Equals(option.ShortName, arg, StringComparison.InvariantCultureIgnoreCase)) ||
86-
(option.HasLongName && string.Equals(option.LongName, arg, StringComparison.InvariantCultureIgnoreCase)));
82+
8783

8884
if (idx < 0 || idx > lstArgs.Count)
8985
{

CommandLineParser/Core/Command/CommandLineCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public CommandLineCommand(IResolverFactory resolverFactory)
2626

2727
public IOptionBuilder<TProperty> Configure<TProperty>(Expression<Func<TSource, TProperty>> selector)
2828
{
29-
var option = new CommandLineArgumentOption<TSource, TProperty>(source, selector, resolverFactory.CreateResolver<TProperty>());
29+
var option = new CommandLineOption<TSource, TProperty>(source, selector, resolverFactory.CreateResolver<TProperty>());
3030

3131
options.Add(option);
3232

CommandLineParser/Core/Command/CommandLineCommandBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ internal abstract class CommandLineCommandBase :
2121
public bool IsRequired { get; protected set; }
2222
public bool HasShortName => ShortName != null;
2323
public bool HasLongName => LongName != null;
24+
public bool HasDefault => false;
2425

2526
public abstract void Execute();
2627

CommandLineParser/Core/CommandLineArgumentOption.cs renamed to CommandLineParser/Core/CommandLineOption.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
namespace MatthiWare.CommandLine.Core
99
{
10-
internal class CommandLineArgumentOption<TSource, TProperty> :
11-
CommandLineArgumentOptionBase,
10+
internal class CommandLineOption<TSource, TProperty> :
11+
CommandLineOptionBase,
1212
ICommandLineOption<TProperty>,
1313
IOptionBuilder<TProperty> where TSource : class
1414
{
@@ -17,7 +17,7 @@ internal class CommandLineArgumentOption<TSource, TProperty> :
1717
private TProperty m_defaultValue = default(TProperty);
1818
private readonly ICommandLineArgumentResolver<TProperty> resolver;
1919

20-
public CommandLineArgumentOption(TSource source, Expression<Func<TSource, TProperty>> selector, ICommandLineArgumentResolver<TProperty> resolver)
20+
public CommandLineOption(TSource source, Expression<Func<TSource, TProperty>> selector, ICommandLineArgumentResolver<TProperty> resolver)
2121
{
2222
this.source = source ?? throw new ArgumentNullException(nameof(source));
2323
this.selector = selector ?? throw new ArgumentNullException(nameof(selector));

CommandLineParser/Core/CommandLineArgumentOptionBase.cs renamed to CommandLineParser/Core/CommandLineOptionBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace MatthiWare.CommandLine.Core
1010
{
1111
[DebuggerDisplay("Cmd Option {ShortName ?? LongName}, Req: {IsRequired}, HasDefault: {HasDefault}")]
12-
internal abstract class CommandLineArgumentOptionBase : IParser, ICommandLineOption
12+
internal abstract class CommandLineOptionBase : IParser, ICommandLineOption
1313
{
1414
public string ShortName { get; protected set; }
1515
public string LongName { get; protected set; }
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using MatthiWare.CommandLine.Abstractions.Command;
2+
using MatthiWare.CommandLine.Abstractions.Parsing;
3+
using MatthiWare.CommandLine.Core.Command;
4+
using System;
5+
using System.Linq;
6+
using System.Collections.Generic;
7+
using System.Text;
8+
using MatthiWare.CommandLine.Abstractions;
9+
10+
namespace MatthiWare.CommandLine.Core.Parsing
11+
{
12+
internal class ArgumentManager : IArgumentGrouper, IDisposable
13+
{
14+
private IDictionary<ICommandLineCommand, string> arguments;
15+
16+
public ArgumentManager(string[] args, List<CommandLineCommandBase> commands, List<CommandLineOptionBase> options)
17+
{
18+
arguments = new Dictionary<ICommandLineCommand, string>(commands.Count + options.Count);
19+
20+
var lstArgs = new List<ArgumentValueHolder>(args.Select(arg => new ArgumentValueHolder
21+
{
22+
Argument = arg,
23+
Used = false
24+
}));
25+
26+
Parse(lstArgs, commands);
27+
28+
Parse(lstArgs, options);
29+
30+
foreach (var item in lstArgs)
31+
{
32+
if (item.Used) continue;
33+
34+
item.Used = true;
35+
36+
arguments.Add(item.Command, item.Argument);
37+
}
38+
}
39+
40+
private void Parse(List<ArgumentValueHolder> args, IEnumerable<ICommandLineCommand> list)
41+
{
42+
foreach (var item in list)
43+
{
44+
int idx = args.FindIndex(arg => !arg.Used &&
45+
((item.HasShortName && string.Equals(item.ShortName, arg.Argument, StringComparison.InvariantCultureIgnoreCase)) ||
46+
(item.HasLongName && string.Equals(item.LongName, arg.Argument, StringComparison.InvariantCultureIgnoreCase))));
47+
48+
args[idx].Used = true;
49+
args[idx].Command = item;
50+
}
51+
}
52+
53+
public void Dispose()
54+
{
55+
arguments.Clear();
56+
}
57+
58+
public bool TryGetValue(ICommandLineCommand cmd, out string value) => arguments.TryGetValue(cmd, out value);
59+
60+
private class ArgumentValueHolder
61+
{
62+
public string Argument { get; set; }
63+
public bool Used { get; set; }
64+
public ICommandLineCommand Command { get; set; }
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)