Skip to content

Commit e594f2e

Browse files
committed
Type CLI parse results
1 parent ef1eec5 commit e594f2e

7 files changed

Lines changed: 201 additions & 79 deletions

File tree

src/PlateauResoniteLink.Cli/CliApplication.cs

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Diagnostics.CodeAnalysis;
45
using System.Globalization;
56
using System.IO;
@@ -45,25 +46,19 @@ public async Task<int> RunAsync(string[] args, CancellationToken cancellationTok
4546
{
4647
CliParseResult parseResult = CliArgumentsParser.Parse(args);
4748

48-
if (parseResult.ShowHelp)
49-
{
50-
await standardOutput.WriteLineAsync(CliArgumentsParser.HelpText);
51-
return 0;
52-
}
53-
54-
if (parseResult.Error is not null)
55-
{
56-
await standardError.WriteLineAsync(parseResult.Error);
57-
await standardError.WriteLineAsync();
58-
await standardError.WriteLineAsync(CliArgumentsParser.HelpText);
59-
return 1;
60-
}
61-
6249
try
6350
{
64-
switch (parseResult.Command)
51+
switch (parseResult)
6552
{
66-
case ImportCommandOptions options:
53+
case CliParseResult.HelpResult:
54+
await standardOutput.WriteLineAsync(CliArgumentsParser.HelpText);
55+
return 0;
56+
case CliParseResult.FailureResult failure:
57+
await standardError.WriteLineAsync(failure.Error);
58+
await standardError.WriteLineAsync();
59+
await standardError.WriteLineAsync(CliArgumentsParser.HelpText);
60+
return 1;
61+
case CliParseResult.ImportSuccessResult { Command: ImportCommandOptions options }:
6762
{
6863
Action<string> reporter = CreateReporter(options.VerboseLogging);
6964
PlateauImportService effectiveImportService = importServiceFactory.Create(options, reporter);
@@ -97,7 +92,7 @@ public async Task<int> RunAsync(string[] args, CancellationToken cancellationTok
9792

9893
return 0;
9994
}
100-
case SearchCommandOptions options:
95+
case CliParseResult.SearchSuccessResult { Command: SearchCommandOptions options }:
10196
{
10297
DatasetSearchResult result = await datasetInspectionService.SearchAsync(
10398
options.CityGmlSourcePath,
@@ -107,7 +102,7 @@ public async Task<int> RunAsync(string[] args, CancellationToken cancellationTok
107102
await WriteSearchResultAsync(result, options.OutputFormat, cancellationToken);
108103
return 0;
109104
}
110-
case StatsCommandOptions options:
105+
case CliParseResult.StatsSuccessResult { Command: StatsCommandOptions options }:
111106
{
112107
DatasetStatsResult result = await datasetInspectionService.GetStatsAsync(
113108
options.CityGmlSourcePath,
@@ -117,7 +112,7 @@ public async Task<int> RunAsync(string[] args, CancellationToken cancellationTok
117112
return 0;
118113
}
119114
default:
120-
throw new InvalidOperationException("CLI parse succeeded without a supported command payload.");
115+
throw new UnreachableException();
121116
}
122117
}
123118
catch (PlateauImportValidationException exception)
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
namespace PlateauResoniteLink.Cli;
22

3-
public abstract record CliCommandOptions;
3+
public abstract class CliCommandOptions
4+
{
5+
private protected CliCommandOptions()
6+
{
7+
}
8+
}
Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,89 @@
1+
using System;
2+
13
namespace PlateauResoniteLink.Cli;
24

3-
public sealed record CliParseResult(
4-
CliCommandOptions? Command,
5-
string? Error,
6-
bool ShowHelp)
5+
public abstract class CliParseResult
76
{
8-
public ImportCommandOptions? Options => Command as ImportCommandOptions;
7+
private CliParseResult()
8+
{
9+
}
910

1011
public static CliParseResult Failure(string error)
1112
{
12-
return new CliParseResult(null, error, ShowHelp: false);
13+
return new FailureResult(error);
1314
}
1415

1516
public static CliParseResult Help()
1617
{
17-
return new CliParseResult(null, null, ShowHelp: true);
18+
return HelpResult.Instance;
19+
}
20+
21+
public static CliParseResult Success(ImportCommandOptions command)
22+
{
23+
return new ImportSuccessResult(command);
24+
}
25+
26+
public static CliParseResult Success(SearchCommandOptions command)
27+
{
28+
return new SearchSuccessResult(command);
29+
}
30+
31+
public static CliParseResult Success(StatsCommandOptions command)
32+
{
33+
return new StatsSuccessResult(command);
34+
}
35+
36+
public sealed class ImportSuccessResult : CliParseResult
37+
{
38+
public ImportSuccessResult(ImportCommandOptions command)
39+
{
40+
Command = command ?? throw new ArgumentNullException(nameof(command));
41+
}
42+
43+
public ImportCommandOptions Command { get; }
44+
}
45+
46+
public sealed class SearchSuccessResult : CliParseResult
47+
{
48+
public SearchSuccessResult(SearchCommandOptions command)
49+
{
50+
Command = command ?? throw new ArgumentNullException(nameof(command));
51+
}
52+
53+
public SearchCommandOptions Command { get; }
1854
}
1955

20-
public static CliParseResult Success(CliCommandOptions command)
56+
public sealed class StatsSuccessResult : CliParseResult
2157
{
22-
return new CliParseResult(command, null, ShowHelp: false);
58+
public StatsSuccessResult(StatsCommandOptions command)
59+
{
60+
Command = command ?? throw new ArgumentNullException(nameof(command));
61+
}
62+
63+
public StatsCommandOptions Command { get; }
64+
}
65+
66+
public sealed class FailureResult : CliParseResult
67+
{
68+
public FailureResult(string error)
69+
{
70+
if (string.IsNullOrWhiteSpace(error))
71+
{
72+
throw new ArgumentException("CLI parse failure message must be provided.", nameof(error));
73+
}
74+
75+
Error = error;
76+
}
77+
78+
public string Error { get; }
79+
}
80+
81+
public sealed class HelpResult : CliParseResult
82+
{
83+
public static HelpResult Instance { get; } = new();
84+
85+
private HelpResult()
86+
{
87+
}
2388
}
2489
}

src/PlateauResoniteLink.Cli/ImportCommandOptions.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace PlateauResoniteLink.Cli;
66

7-
public sealed record ImportCommandOptions(
7+
public sealed class ImportCommandOptions(
88
PlateauImportRequest Request,
99
string WorkRoot,
1010
Uri? ResoniteLinkUri,
@@ -15,4 +15,27 @@ public sealed record ImportCommandOptions(
1515
bool DisableTerrainTileCache,
1616
string? CanonicalSceneDumpPath,
1717
bool EnableSendMetrics,
18-
bool VerboseLogging) : CliCommandOptions;
18+
bool VerboseLogging) : CliCommandOptions
19+
{
20+
public PlateauImportRequest Request { get; } = Request ?? throw new ArgumentNullException(nameof(Request));
21+
22+
public string WorkRoot { get; } = WorkRoot ?? throw new ArgumentNullException(nameof(WorkRoot));
23+
24+
public Uri? ResoniteLinkUri { get; } = ResoniteLinkUri;
25+
26+
public int ResoniteLinkConnectionCount { get; } = ResoniteLinkConnectionCount;
27+
28+
public PlateauImportMemoryProfile MemoryProfile { get; } = MemoryProfile;
29+
30+
public bool EnableMeshBake { get; } = EnableMeshBake;
31+
32+
public string? TerrainTileCacheRoot { get; } = TerrainTileCacheRoot;
33+
34+
public bool DisableTerrainTileCache { get; } = DisableTerrainTileCache;
35+
36+
public string? CanonicalSceneDumpPath { get; } = CanonicalSceneDumpPath;
37+
38+
public bool EnableSendMetrics { get; } = EnableSendMetrics;
39+
40+
public bool VerboseLogging { get; } = VerboseLogging;
41+
}
Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1+
using System;
12
using System.Collections.Generic;
23

34
namespace PlateauResoniteLink.Cli;
45

5-
public sealed record SearchCommandOptions(
6-
string CityGmlSourcePath,
7-
string MeshCode,
8-
IReadOnlyList<string>? PackageNames,
9-
CliOutputFormat OutputFormat) : CliCommandOptions;
6+
public sealed class SearchCommandOptions(
7+
string cityGmlSourcePath,
8+
string meshCode,
9+
IReadOnlyList<string>? packageNames,
10+
CliOutputFormat outputFormat) : CliCommandOptions
11+
{
12+
public string CityGmlSourcePath { get; } = cityGmlSourcePath ?? throw new ArgumentNullException(nameof(cityGmlSourcePath));
13+
14+
public string MeshCode { get; } = meshCode ?? throw new ArgumentNullException(nameof(meshCode));
15+
16+
public IReadOnlyList<string>? PackageNames { get; } = packageNames;
17+
18+
public CliOutputFormat OutputFormat { get; } = outputFormat;
19+
}
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1+
using System;
12
using System.Collections.Generic;
23

34
namespace PlateauResoniteLink.Cli;
45

5-
public sealed record StatsCommandOptions(
6-
string CityGmlSourcePath,
7-
IReadOnlyList<string>? PackageNames,
8-
CliOutputFormat OutputFormat) : CliCommandOptions;
6+
public sealed class StatsCommandOptions(
7+
string cityGmlSourcePath,
8+
IReadOnlyList<string>? packageNames,
9+
CliOutputFormat outputFormat) : CliCommandOptions
10+
{
11+
public string CityGmlSourcePath { get; } = cityGmlSourcePath ?? throw new ArgumentNullException(nameof(cityGmlSourcePath));
12+
13+
public IReadOnlyList<string>? PackageNames { get; } = packageNames;
14+
15+
public CliOutputFormat OutputFormat { get; } = outputFormat;
16+
}

0 commit comments

Comments
 (0)