This repository was archived by the owner on Jun 11, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
103 lines (87 loc) · 3.72 KB
/
Copy pathProgram.cs
File metadata and controls
103 lines (87 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Antlr4.Runtime;
using CommandLine;
using DiscordMessageTemplate.Antlr;
using DiscordMessageTemplate.Compiler;
using JsonSerializer = System.Text.Json.JsonSerializer;
using Parser = CommandLine.Parser;
namespace DiscordMessageTemplate;
public class CommandLineOptions
{
public static CommandLineOptions Current { get; internal set; }
[Option('n', "nulls", HelpText = "Include null values")]
public bool PrintNulls { get; set; }
[Option('p', "pretty", HelpText = "Pretty printing")]
public bool Prettify { get; set; }
[Option('c', "context", HelpText = "Context JSON file to load before eval", Default = "context.json")]
public string Context { get; set; }
[Value(0, HelpText = "Input path", Required = true)]
public string InputFile { get; set; }
}
public class Program
{
public static void Main(params string[] args)
{
Parser.Default.ParseArguments<CommandLineOptions>(args)
.WithParsed(result =>
{
CommandLineOptions.Current = result;
var template = File.ReadAllText(result.InputFile);
EvalAndPrintTemplate(template);
});
}
// ReSharper disable once MemberCanBePrivate.Global
public static string EvalTemplate(string template)
{
TryLoadContext();
var result = Evaluate(template);
return JsonSerializer.Serialize(result,
new JsonSerializerOptions
{
WriteIndented = CommandLineOptions.Current.Prettify,
DefaultIgnoreCondition = CommandLineOptions.Current.PrintNulls ? JsonIgnoreCondition.Never : JsonIgnoreCondition.WhenWritingNull
});
}
private static void TryLoadContext()
{
var path = CommandLineOptions.Current.Context;
if (!File.Exists(path)) return;
var context = JsonSerializer.Deserialize<Dictionary<string, object?>>(File.OpenRead(path));
if (context is null) return;
context = context.ToDictionary(e => e.Key, e => UnwrapJson(e.Value));
foreach (var (key, value) in context)
RootContext.Instance.Constants[key] = value;
}
private static object? UnwrapJson(object? value) => value switch
{
JsonObject obj => obj.ToDictionary(e => e.Key, e => UnwrapJson(e.Value)),
JsonArray arr => arr.Select(UnwrapJson).ToList(),
JsonElement { ValueKind: JsonValueKind.Object } obj => obj.EnumerateObject().ToDictionary(e => e.Name, e => UnwrapJson(e.Value)),
JsonElement { ValueKind: JsonValueKind.Array } arr => arr.EnumerateArray().Cast<object>().Select(UnwrapJson).ToList(),
JsonElement { ValueKind: JsonValueKind.String } str => str.GetString(),
JsonElement { ValueKind: JsonValueKind.Number } num => num.GetDouble(),
JsonElement { ValueKind: JsonValueKind.True } => true,
JsonElement { ValueKind: JsonValueKind.False } => false,
JsonElement { ValueKind: JsonValueKind.Null } => null,
_ => value
};
private static void EvalAndPrintTemplate(string template)
{
var json = EvalTemplate(template);
Console.WriteLine(json);
}
public static MessageData Evaluate(string template)
{
var input = new AntlrInputStream(new StringReader(template));
var lexer = new DiscordMessageTemplateLexer(input);
var tokens = new CommonTokenStream(lexer);
var parser = new DiscordMessageTemplateParser(tokens);
var visitor = new Visitor();
var file = parser.template();
var templateRoot = visitor.Visit(file);
templateRoot.Evaluate(RootContext.Instance);
return RootContext.Instance.Message;
}
}