Skip to content

Commit fa5ac09

Browse files
committed
✅ Makes parsing work
1 parent 976955e commit fa5ac09

9 files changed

Lines changed: 73 additions & 30 deletions

File tree

CommandLineParser.Tests/CommandLineArgumentOptionTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Text;
44
using Xunit;
55

6-
namespace CommandLineParser.Tests
6+
namespace MatthiWare.CommandLineParser.Tests
77
{
88

99
public class CommandLineArgumentOptionTest

CommandLineParser.Tests/UnitTest1.cs renamed to CommandLineParser.Tests/ExtensionsTests.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
using Moq;
66
using Xunit;
77

8-
namespace CommandLineParser.Tests
8+
namespace MatthiWare.CommandLineParser.Tests
99
{
10-
public class UnitTest1
10+
public class ExtensionsTests
1111
{
1212
[Fact]
1313
public void Test1()
@@ -72,7 +72,7 @@ public void TestV1()
7272
{
7373
var testString = "this is my test string \"with some quotes\" the end. '\"Here is some literal\"' ";
7474

75-
var resultArr = new string[] { "this", "is", "my", "test", "string", "with some quotes", "the", "end.", "\"Here is some literal\"" };
75+
var resultArr = new string[] { "this", "is", "my", "test", "string", "with some quotes", "the", "end.", "\"Here is some literal\"", " " };
7676

7777
int i = 0;
7878
foreach (var token in Extensions.SplitOnWhitespace(testString))
@@ -86,6 +86,7 @@ public void TestV1()
8686
[Theory]
8787
[InlineData("\"with some quotes\"", "with some quotes")]
8888
[InlineData("'\"with some quotes\"'", "\"with some quotes\"")]
89+
[InlineData("test", "test")]
8990
public void TestRemoveLiteralAndDoubleQuotes(string input, string result)
9091
{
9192
Assert.Equal(result, input.AsSpan().RemoveLiteralsAndQuotes());

CommandLineParser.Tests/OptionBuilderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
using Moq;
88
using Xunit;
99

10-
namespace CommandLineParser.Tests
10+
namespace MatthiWare.CommandLineParser.Tests
1111
{
1212
public class OptionBuilderTest
1313
{
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using MatthiWare.CommandLine.Abstractions.Models;
5+
using MatthiWare.CommandLine.Core.Parsing.Resolvers;
6+
using Xunit;
7+
8+
namespace MatthiWare.CommandLineParser.Tests.Parsing.Resolvers
9+
{
10+
public class StringResovlerTests
11+
{
12+
13+
[Theory]
14+
[InlineData(true, "-m", "test")]
15+
public void TestCanResolve(bool expected, string key, string value)
16+
{
17+
var resolver = new StringResolver();
18+
var model = new ArgumentModel(key, value);
19+
20+
Assert.Equal(expected, resolver.CanResolve(model));
21+
}
22+
23+
[Theory]
24+
[InlineData("test", "-m", "test")]
25+
public void TestResolve(string expected, string key, string value)
26+
{
27+
var resolver = new StringResolver();
28+
var model = new ArgumentModel(key, value);
29+
30+
Assert.Equal(expected, resolver.Resolve(model));
31+
}
32+
33+
}
34+
}

CommandLineParser/Abstractions/Models/ArgumentModel.cs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,24 @@
44

55
namespace MatthiWare.CommandLine.Abstractions.Models
66
{
7-
public class ArgumentModel
7+
public struct ArgumentModel
88
{
9-
private string m_value = null;
10-
11-
129
public string Key { get; set; }
1310

11+
public string Value { get; set; }
1412

15-
public string Value
16-
{
17-
get => m_value;
18-
set
19-
{
20-
HasValue = true;
21-
m_value = value;
22-
}
23-
}
24-
25-
public bool HasValue { get; private set; }
13+
public bool HasValue => Value != null;
2614

2715
public ArgumentModel(string key, string value)
2816
{
2917
this.Key = key;
3018
this.Value = value;
3119
}
3220

33-
public ArgumentModel()
21+
public ArgumentModel(string key)
3422
{
35-
23+
this.Key = key;
24+
this.Value = null;
3625
}
3726

3827
}

CommandLineParser/Abstractions/Parsing/IParser.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace MatthiWare.CommandLine.Abstractions.Parsing
77
{
88
public interface IParser
99
{
10+
bool CanParse(ArgumentModel model);
1011
void Parse(ArgumentModel model);
1112
}
1213
}

CommandLineParser/CommandLineParser.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Runtime.CompilerServices;
66
using System.Text;
77
using MatthiWare.CommandLine.Abstractions;
8+
using MatthiWare.CommandLine.Abstractions.Models;
89
using MatthiWare.CommandLine.Abstractions.Parsing;
910
using MatthiWare.CommandLine.Core;
1011
using MatthiWare.CommandLine.Core.Parsing;
@@ -66,13 +67,27 @@ public IParserResult<TSource> Parse(string[] args)
6667
(option.HasShortName && string.Equals(option.ShortName, arg, StringComparison.InvariantCultureIgnoreCase)) ||
6768
(option.HasLongName && string.Equals(option.LongName, arg, StringComparison.InvariantCultureIgnoreCase)));
6869

69-
if (idx < 0 && option.IsRequired)
70+
if ((idx < 0 || idx > lstArgs.Count) && option.IsRequired)
7071
{
7172
errors.Add(new KeyNotFoundException($"Required argument '{option.HasShortName}' or '{option.LongName}' not found"));
7273
continue;
7374
}
7475

75-
var argument = lstArgs[idx];
76+
var key = lstArgs[idx];
77+
var value = ++idx < lstArgs.Count ? lstArgs[idx] : null;
78+
79+
var argModel = new ArgumentModel(key, value);
80+
81+
var parser = option as IParser;
82+
83+
if (!parser.CanParse(argModel))
84+
{
85+
errors.Add(new ArgumentException($"Cannot parse option '{argModel.Key}:{argModel.Value ?? "NULL"}'"));
86+
87+
continue;
88+
}
89+
90+
parser.Parse(argModel);
7691
}
7792

7893
if (errors.Any())

CommandLineParser/Core/CommandLineArgumentOption.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,11 @@ public TProperty DefaultValue
4444

4545
public bool HasLongName => !string.IsNullOrWhiteSpace(LongName);
4646

47-
public void Parse(ArgumentModel model)
48-
{
49-
if (!resolver.CanResolve(model)) throw new ArgumentException("Invalid argument option", nameof(model));
50-
47+
public bool CanParse(ArgumentModel model)
48+
=> resolver.CanResolve(model);
5149

52-
}
50+
public void Parse(ArgumentModel model)
51+
=> AssignValue(resolver.Resolve(model));
5352

5453
IOptionBuilder<TProperty> IOptionBuilder<TProperty>.Default(TProperty defaultValue)
5554
{

CommandLineParser/Core/Extensions.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private static string FindNextWord(ReadOnlySpan<char> src, out int read)
7878
}
7979
}
8080

81-
return null;
81+
return src.ToString();
8282
}
8383

8484
public static ReadOnlySpan<char> Substring(this ReadOnlySpan<char> src, int start, int len)
@@ -95,12 +95,16 @@ public static string RemoveLiteralsAndQuotes(this ReadOnlySpan<char> value)
9595
int startTrim = 0, endTrim = 0;
9696
int len = value.Length - 1;
9797

98+
if (value.Length == 0) return new string(value.ToArray());
99+
98100
if (value[0] == DoubleQuote || value[0] == SingleQuote)
99101
startTrim = 1;
100102

101103
if (value[len] == DoubleQuote || value[len] == SingleQuote)
102104
endTrim = 1;
103105

106+
if (startTrim == 0 && endTrim == 0) return new string(value.ToArray());
107+
104108
return new string(value.Substring(startTrim, len - endTrim).ToArray());
105109
}
106110

0 commit comments

Comments
 (0)