Skip to content

Commit c7834c4

Browse files
authored
Merge pull request #16 from HappyHackingSpace/refactor/entrypoint
2 parents 9faf74f + a43dfc6 commit c7834c4

12 files changed

Lines changed: 111 additions & 45 deletions

File tree

funURL.CLI.Tests/UrlOperationsTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using funURL.CLI.Core;
2-
using LanguageExt;
32

43
namespace funURL.CLI.Tests;
54

funURL.CLI/Commands/DecodeCommand.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System.CommandLine;
22
using funURL.CLI.Core;
3-
using LanguageExt;
4-
using static LanguageExt.Prelude;
3+
using funURL.CLI.Functional;
54

65
namespace funURL.CLI.Commands;
76

@@ -11,10 +10,7 @@ namespace funURL.CLI.Commands;
1110
public class DecodeCommand : Command
1211
{
1312
private readonly Argument<string> inputArgument = new("input") { Description = "String to decode" };
14-
private readonly System.CommandLine.Option<bool> queryOption = new("--query", "-c")
15-
{
16-
Description = "Decode as query component (handles + as spaces)",
17-
};
13+
private readonly Option<bool> queryOption = new("--query", "-c") { Description = "Decode as query component (handles + as spaces)" };
1814

1915
private DecodeCommand()
2016
: base("decode", "URL-decode a string")

funURL.CLI/Commands/DedupeCommand.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
using System.CommandLine;
22
using System.Text.RegularExpressions;
33
using funURL.CLI.Core;
4-
using LanguageExt;
5-
using static LanguageExt.Prelude;
4+
using funURL.CLI.Functional;
65

76
namespace funURL.CLI.Commands;
87

funURL.CLI/Commands/EncodeCommand.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System.CommandLine;
22
using funURL.CLI.Core;
3-
using LanguageExt;
4-
using static LanguageExt.Prelude;
3+
using funURL.CLI.Functional;
54

65
namespace funURL.CLI.Commands;
76

@@ -11,10 +10,7 @@ namespace funURL.CLI.Commands;
1110
public class EncodeCommand : Command
1211
{
1312
private readonly Argument<string> inputArgument = new("input") { Description = "String to encode" };
14-
private readonly System.CommandLine.Option<bool> queryOption = new("--query", "-c")
15-
{
16-
Description = "Encode as query component (uses + for spaces)",
17-
};
13+
private readonly Option<bool> queryOption = new("--query", "-c") { Description = "Encode as query component (uses + for spaces)" };
1814

1915
private EncodeCommand()
2016
: base("encode", "URL-encode a string")

funURL.CLI/Commands/ModifyCommand.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System.CommandLine;
22
using funURL.CLI.Core;
3-
using LanguageExt;
4-
using static LanguageExt.Prelude;
3+
using funURL.CLI.Functional;
54

65
namespace funURL.CLI.Commands;
76

@@ -11,10 +10,10 @@ namespace funURL.CLI.Commands;
1110
public class ModifyCommand : Command
1211
{
1312
private readonly Argument<string> urlArgument = new("url") { Description = "URL to modify" };
14-
private readonly System.CommandLine.Option<string?> protocolOption = new("--protocol", "-c") { Description = "Change protocol/scheme" };
15-
private readonly System.CommandLine.Option<string?> pathOption = new("--path", "-p") { Description = "Update path" };
16-
private readonly System.CommandLine.Option<string?> queryOption = new("--query", "-q") { Description = "Change query string" };
17-
private readonly System.CommandLine.Option<string?> fragmentOption = new("--fragment", "-f") { Description = "Update fragment" };
13+
private readonly Option<string?> protocolOption = new("--protocol", "-c") { Description = "Change protocol/scheme" };
14+
private readonly Option<string?> pathOption = new("--path", "-p") { Description = "Update path" };
15+
private readonly Option<string?> queryOption = new("--query", "-q") { Description = "Change query string" };
16+
private readonly Option<string?> fragmentOption = new("--fragment", "-f") { Description = "Update fragment" };
1817

1918
private ModifyCommand()
2019
: base("modify", "Modify components of a URL")

funURL.CLI/Commands/ParseCommand.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System.CommandLine;
22
using funURL.CLI.Core;
3-
using LanguageExt;
4-
using static LanguageExt.Prelude;
3+
using funURL.CLI.Functional;
54

65
namespace funURL.CLI.Commands;
76

@@ -11,13 +10,13 @@ namespace funURL.CLI.Commands;
1110
public class ParseCommand : Command
1211
{
1312
private readonly Argument<string> urlArgument = new("url") { Description = "URL to parse" };
14-
private readonly System.CommandLine.Option<bool> protocolOption = new("--protocol", "-c") { Description = "Extract protocol/scheme" };
15-
private readonly System.CommandLine.Option<bool> subdomainOption = new("--subdomain", "-s") { Description = "Extract subdomain" };
16-
private readonly System.CommandLine.Option<bool> tldOption = new("--tld", "-t") { Description = "Extract top-level domain" };
17-
private readonly System.CommandLine.Option<bool> hostnameOption = new("--hostname", "-n") { Description = "Extract hostname" };
18-
private readonly System.CommandLine.Option<bool> pathOption = new("--path", "-p") { Description = "Extract path" };
19-
private readonly System.CommandLine.Option<bool> queryOption = new("--query", "-q") { Description = "Extract query parameters" };
20-
private readonly System.CommandLine.Option<bool> fragmentOption = new("--fragment", "-f") { Description = "Extract fragment" };
13+
private readonly Option<bool> protocolOption = new("--protocol", "-c") { Description = "Extract protocol/scheme" };
14+
private readonly Option<bool> subdomainOption = new("--subdomain", "-s") { Description = "Extract subdomain" };
15+
private readonly Option<bool> tldOption = new("--tld", "-t") { Description = "Extract top-level domain" };
16+
private readonly Option<bool> hostnameOption = new("--hostname", "-n") { Description = "Extract hostname" };
17+
private readonly Option<bool> pathOption = new("--path", "-p") { Description = "Extract path" };
18+
private readonly Option<bool> queryOption = new("--query", "-q") { Description = "Extract query parameters" };
19+
private readonly Option<bool> fragmentOption = new("--fragment", "-f") { Description = "Extract fragment" };
2120

2221
private ParseCommand()
2322
: base("parse", "Parse and extract components from a URL")

funURL.CLI/Commands/RootCommand.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.CommandLine;
2+
using Figgle.Fonts;
3+
4+
namespace funURL.CLI.Commands;
5+
6+
/// <summary>
7+
/// The root command for the funURL CLI.
8+
/// </summary>
9+
public class RootCommand : System.CommandLine.RootCommand
10+
{
11+
private readonly Option<bool> silentOption = new("--silent", "-s") { Description = "Suppress the startup banner", Recursive = true };
12+
13+
private RootCommand()
14+
: base("funURL - A Functional URL Swiss Army Knife")
15+
{
16+
Options.Add(silentOption);
17+
Subcommands.Add(ParseCommand.Create());
18+
Subcommands.Add(ModifyCommand.Create());
19+
Subcommands.Add(EncodeCommand.Create());
20+
Subcommands.Add(DecodeCommand.Create());
21+
Subcommands.Add(DedupeCommand.Create());
22+
}
23+
24+
public async Task<ParseResult> Parse(IReadOnlyList<string> args, CancellationToken cancellationToken)
25+
{
26+
var parseResult = base.Parse(args, null);
27+
28+
if (!parseResult.GetValue(silentOption))
29+
{
30+
await Console.Out.WriteAsync(FiggleFonts.Standard.Render("funURL").AsMemory(), cancellationToken);
31+
}
32+
33+
return parseResult;
34+
}
35+
36+
public static RootCommand Create() => new();
37+
}

funURL.CLI/Core/UrlOperations.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System.Net;
2-
using LanguageExt;
3-
using LanguageExt.Common;
4-
using static LanguageExt.Prelude;
2+
using funURL.CLI.Functional;
53

64
namespace funURL.CLI.Core;
75

funURL.CLI/Functional/Error.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace funURL.CLI.Functional;
2+
3+
internal sealed class Error(string message)
4+
{
5+
public string Message { get; } = message;
6+
7+
public static Error New(string message) => new(message);
8+
}

funURL.CLI/Functional/Fin.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace funURL.CLI.Functional;
2+
3+
internal abstract class Fin<T>
4+
{
5+
public abstract bool IsSucc { get; }
6+
public bool IsFail => !IsSucc;
7+
8+
public static Fin<T> Succ(T value) => new SuccCase(value);
9+
10+
public static implicit operator Fin<T>(Error error) => new FailCase(error);
11+
12+
public abstract Fin<TResult> Map<TResult>(Func<T, TResult> mapper);
13+
14+
public abstract Task Match(Func<T, Task> Succ, Func<Error, Task> Fail);
15+
16+
public abstract T ThrowIfFail();
17+
18+
private sealed class SuccCase(T value) : Fin<T>
19+
{
20+
public override bool IsSucc => true;
21+
22+
public override Fin<TResult> Map<TResult>(Func<T, TResult> mapper) => Fin<TResult>.Succ(mapper(value));
23+
24+
public override Task Match(Func<T, Task> Succ, Func<Error, Task> Fail) => Succ(value);
25+
26+
public override T ThrowIfFail() => value;
27+
}
28+
29+
private sealed class FailCase(Error error) : Fin<T>
30+
{
31+
public override bool IsSucc => false;
32+
33+
public override Fin<TResult> Map<TResult>(Func<T, TResult> mapper) => error;
34+
35+
public override Task Match(Func<T, Task> Succ, Func<Error, Task> Fail) => Fail(error);
36+
37+
public override T ThrowIfFail() => throw new InvalidOperationException(error.Message);
38+
}
39+
}

0 commit comments

Comments
 (0)