Skip to content

Commit

Permalink
Improve help command
Browse files Browse the repository at this point in the history
  • Loading branch information
KubaZ2 committed Aug 20, 2024
1 parent 5426821 commit 4195cbb
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 17 deletions.
3 changes: 3 additions & 0 deletions Bot/Sharp/Compilation/CompilerProvider.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Collections.Frozen;
using System.Runtime.InteropServices;

namespace Sharp.Compilation;

public class CompilerProvider(IEnumerable<ICompiler> compilers) : ICompilerProvider
{
private readonly FrozenDictionary<Language, ICompiler> _compilers = compilers.ToFrozenDictionary(c => c.Language);

public IReadOnlyList<Language> SupportedLanguages => ImmutableCollectionsMarshal.AsArray(_compilers.Keys) ?? [];

public ICompiler? GetCompiler(Language language)
{
return _compilers.GetValueOrDefault(language);
Expand Down
2 changes: 2 additions & 0 deletions Bot/Sharp/Compilation/ICompilerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

public interface ICompilerProvider
{
public IReadOnlyList<Language> SupportedLanguages { get; }

public ICompiler? GetCompiler(Language language);
}
3 changes: 3 additions & 0 deletions Bot/Sharp/Decompilation/DecompilerProvider.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Collections.Frozen;
using System.Runtime.InteropServices;

namespace Sharp.Decompilation;

public class DecompilerProvider(IEnumerable<IDecompiler> decompilers) : IDecompilerProvider
{
private readonly FrozenDictionary<Language, IDecompiler> _decompilers = decompilers.ToFrozenDictionary(c => c.Language);

public IReadOnlyList<Language> SupportedLanguages => ImmutableCollectionsMarshal.AsArray(_decompilers.Keys) ?? [];

public IDecompiler? GetDecompiler(Language language)
{
return _decompilers.GetValueOrDefault(language);
Expand Down
2 changes: 2 additions & 0 deletions Bot/Sharp/Decompilation/IDecompilerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

public interface IDecompilerProvider
{
public IReadOnlyList<Language> SupportedLanguages { get; }

public IDecompiler? GetDecompiler(Language language);
}
8 changes: 8 additions & 0 deletions Bot/Sharp/Names/INameFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Sharp.Names;

public interface INameFormatter
{
public string Format(Language language);

public string Format(BackendArchitecture architecture);
}
32 changes: 32 additions & 0 deletions Bot/Sharp/Names/NameFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Sharp.Names;

public class NameFormatter : INameFormatter
{
public string Format(Language language)
{
return language switch
{
Language.CSharp => "C#",
Language.VisualBasic => "VB",
Language.FSharp => "F#",
Language.IL => "IL",
Language.X64 => "x64",
Language.X86 => "x86",
Language.Arm64 => "ARM64",
Language.Arm32 => "ARM32",
_ => throw new ArgumentOutOfRangeException(nameof(language))
};
}

public string Format(BackendArchitecture architecture)
{
return architecture switch
{
BackendArchitecture.X86 => "x86",
BackendArchitecture.X64 => "x64",
BackendArchitecture.Arm32 => "ARM32",
BackendArchitecture.Arm64 => "ARM64",
_ => throw new ArgumentOutOfRangeException(nameof(architecture))
};
}
}
2 changes: 2 additions & 0 deletions Bot/Sharp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

using Sharp;
using Sharp.Attachments;
using Sharp.Names;
using Sharp.Backend;
using Sharp.Compilation;
using Sharp.CompilationResponse;
Expand All @@ -35,6 +36,7 @@
services
.AddHttpClient()
.AddMemoryCache()
.AddSingleton<INameFormatter, NameFormatter>()
.AddSingleton<IAttachmentCodeProvider, AttachmentCodeProvider>()
.AddSingleton<ILanguageFormatProvider, LanguageFormatProvider>()
.AddSingleton<IDiagnosticsFormatter, DiagnosticsFormatter>()
Expand Down
34 changes: 17 additions & 17 deletions Bot/Sharp/Responding/ResponseProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
using NetCord.Rest;

using Sharp.Attachments;
using Sharp.Names;
using Sharp.Backend;
using Sharp.Compilation;
using Sharp.CompilationResponse;
using Sharp.Decompilation;

namespace Sharp.Responding;

public class ResponseProvider(IOptions<Options> options, ICompilationFormatter compilationFormatter, ILanguageFormatProvider languageFormatProvider, IBackendUriProvider backendUriProvider) : IResponseProvider
public class ResponseProvider(IOptions<Options> options, ICompilationFormatter compilationFormatter, ILanguageFormatProvider languageFormatProvider, IBackendUriProvider backendUriProvider, INameFormatter nameFormatter, ICompilerProvider compilerProvider, IDecompilerProvider decompilerProvider) : IResponseProvider
{
public T CompilationResultResponse<T>(ulong operationId, CompilationResult result) where T : IMessageProperties, new()
{
Expand All @@ -41,7 +42,7 @@ public class ResponseProvider(IOptions<Options> options, ICompilationFormatter c

private T CompilerNotFoundResponse<T>(Language language) where T : IMessageProperties, new()
{
return Error<T>("Compiler not found", $"The compiler for the language `{language}` was not found.");
return Error<T>("Compiler not found", $"The compiler for the language {nameFormatter.Format(language)} was not found.");
}

private T CompilationFailResponse<T>(ulong operationId, IReadOnlyList<Diagnostic> diagnostics) where T : IMessageProperties, new()
Expand Down Expand Up @@ -80,17 +81,17 @@ public class ResponseProvider(IOptions<Options> options, ICompilationFormatter c

private T DecompilerNotFoundResponse<T>(Language language) where T : IMessageProperties, new()
{
return Error<T>("Decompiler not found", $"The decompiler for the language `{language}` was not found.");
return Error<T>("Decompiler not found", $"The decompiler for the language {nameFormatter.Format(language)} was not found.");
}

private T DecompilationFailResponse<T>(Language language) where T : IMessageProperties, new()
{
return Error<T>("Decompilation failed", $"The decompilation for the language `{language}` failed.");
return Error<T>("Decompilation failed", $"The decompilation for the language {nameFormatter.Format(language)} failed.");
}

public T LanguageNotFoundResponse<T>(ulong operationId, string? language) where T : IMessageProperties, new()
{
return Error<T>("Language not found", $"The language `{language}` was not found.");
return Error<T>("Language not found", $"The language {language} was not found.");
}

public T UnknownError<T>(string reason) where T : IMessageProperties, new()
Expand Down Expand Up @@ -165,46 +166,45 @@ public class ResponseProvider(IOptions<Options> options, ICompilationFormatter c
var optionsValue = options.Value;
var emojis = optionsValue.Emojis;

var defaultArchitectureFormatted = nameFormatter.Format(optionsValue.Backend.DefaultArchitecture);

var architectures = await backendUriProvider.GetPlatformsAsync();

message.AddEmbeds(new EmbedProperties().WithDescription(
$"""
# {emojis.Help} Help
## {emojis.Command} Commands
- `#run <architecture?> <code>` - runs the provided code, uses {optionsValue.Backend.DefaultArchitecture} architecture by default
- `#run <architecture?> <code>` - runs the provided code, uses {defaultArchitectureFormatted} architecture by default
- `#<language> <code>` - decompiles the provided code to the specified language
- `#<architecture> <code>` - shows the architecture-specific JIT disassembly of the provided code
The code can be provided as is, as a code block or as an attachment.
## {emojis.Support} Support
### Compilation
- C#
- Visual Basic
- F#
- IL
{string.Join('\n', compilerProvider.SupportedLanguages.Select(l => $"- {nameFormatter.Format(l)}"))}
### Decompilation
- C#
- IL
{string.Join('\n', decompilerProvider.SupportedLanguages.Where(l => l <= Language.IL).Select(l => $"- {nameFormatter.Format(l)}"))}
### Architectures
{string.Join('\n', architectures.Select(a => $"- {a}"))}
{string.Join('\n', architectures.Select(a => $"- {nameFormatter.Format((BackendArchitecture)a)}"))}
## {emojis.Example} Examples
### Running C# code:
#run
\```c#
Console.Write("Hello, World!");
\```
### Decompiling F# code to C#:
#c#
\```f#
printf "Hello, World!"
\```
### Decompiling C# code to IL:
#il
\```c#
Console.Write("Hello, World!");
\```
#arm64
### Showing JIT disassembly of C# code for {defaultArchitectureFormatted}:
#{defaultArchitectureFormatted.ToLowerInvariant()}
\```c#
Console.Write("Hello, World!");
\```
Expand Down

0 comments on commit 4195cbb

Please sign in to comment.