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(PrintArray); Visitors.Register(PrintObject); Visitors.Register(PrintString); Visitors.Register(PrintNumber); Visitors.Register(PrintBool); Visitors.Register(PrintNull); } public static string Format(string source, Context? context) { var nodes = JsonParser.Parse("", 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"); } }