jtr/DevDisciples.Json.Tools/JsonFormatter.cs
2024-09-16 22:46:53 +02:00

106 lines
3.4 KiB
C#

using DevDisciples.Json.Parser;
using DevDisciples.Parsing;
namespace DevDisciples.Json.Tools;
public static partial class JsonFormatter
{
public static VisitorContainer Visitors { get; }
static JsonFormatter()
{
Visitors = new();
Visitors.Register<JsonArray>(PrintArray);
Visitors.Register<JsonObject>(PrintObject);
Visitors.Register<JsonString>(PrintString);
Visitors.Register<JsonNumber>(PrintNumber);
Visitors.Register<JsonBool>(PrintBool);
Visitors.Register<JsonNull>(PrintNull);
}
public static string Format(string source, Context? context)
{
var nodes = JsonParser.Parse("<source>", source);
return Format(nodes, context);
}
private static string Format(ISyntaxNode visitee, Context? context = null)
{
var ctx = context ?? new();
Visitors[visitee.GetType()](visitee, ctx);
return context!.Builder.ToString();
}
private static Context ContextFromArgs(object[] args)
{
return (args[0] as Context)!;
}
private static void PrintArray(object visitee, object[] args)
{
var context = ContextFromArgs(args);
var array = (JsonArray)visitee;
context.Builder.Append($"[{context.NewLine}");
context.IncrementDepth();
for (var i = 0; i < array.Elements.Length; i++)
{
var node = array.Elements[i];
context.Builder.Append(context.Indent);
Visitors[node.GetType()](node, args);
if (i < array.Elements.Length - 1) context.Builder.Append($",{context.NewLine}");
}
context.DecrementDepth();
context.Builder.Append($"{context.NewLine}{context.Indent}]");
}
private static void PrintObject(object visitee, object[] args)
{
var context = ContextFromArgs(args);
var @object = (JsonObject)visitee;
context.Builder.Append($"{{{context.NewLine}");
context.IncrementDepth();
var count = @object.Properties.Length;
for (var i = 0; i < count; i++)
{
var property = @object.Properties.ElementAt(i);
context.Builder.Append($"{context.Indent}\"{property.Key}\":{context.Space}");
Visitors[property.Value.GetType()](property.Value, args);
if (i < count - 1) context.Builder.Append($",{context.NewLine}");
}
context.DecrementDepth();
context.Builder.Append($"{context.NewLine}{context.Indent}}}");
}
private static void PrintString(object visitee, object[] args)
{
var context = ContextFromArgs(args);
var @string = (JsonString)visitee;
context.Builder.Append($"\"{@string.Token.Lexeme}\"");
}
private static void PrintNumber(object visitee, object[] args)
{
var context = ContextFromArgs(args);
var number = (JsonNumber)visitee;
context.Builder.Append($"{number.Value}");
}
private static void PrintBool(object visitee, object[] args)
{
var context = ContextFromArgs(args);
var @bool = (JsonBool)visitee;
context.Builder.Append($"{@bool.Value.ToString().ToLower()}");
}
private static void PrintNull(object visitee, object[] args)
{
var context = ContextFromArgs(args);
context.Builder.Append("null");
}
}