106 lines
3.4 KiB
C#
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.Count; i++)
|
|
{
|
|
var node = array.Elements[i];
|
|
context.Builder.Append(context.Indent);
|
|
Visitors[node.GetType()](node, args);
|
|
if (i < array.Elements.Count - 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.Count;
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var (key, node) = @object.Properties.ElementAt(i);
|
|
context.Builder.Append($"{context.Indent}\"{key}\":{context.Space}");
|
|
Visitors[node.GetType()](node, 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");
|
|
}
|
|
} |