Commit 223f62acbd

Jonathan Marler <johnnymarler@gmail.com>
2023-09-14 00:24:59
std.json: add fmt function (#17055)
Adds std.json.fmt which returns a std.fmt Formatter that formats any given value using std.json.stringify.
1 parent 0e2f002
Changed files (2)
lib
lib/std/json/fmt.zig
@@ -0,0 +1,46 @@
+const std = @import("std");
+
+const stringify = @import("stringify.zig").stringify;
+const StringifyOptions = @import("stringify.zig").StringifyOptions;
+
+/// Returns a formatter that formats the given value using stringify.
+pub fn fmt(value: anytype, options: StringifyOptions) Formatter(@TypeOf(value)) {
+    return Formatter(@TypeOf(value)){ .value = value, .options = options };
+}
+
+/// Formats the given value using stringify.
+pub fn Formatter(comptime T: type) type {
+    return struct {
+        value: T,
+        options: StringifyOptions,
+
+        pub fn format(
+            self: @This(),
+            comptime fmt_spec: []const u8,
+            options: std.fmt.FormatOptions,
+            writer: anytype,
+        ) !void {
+            _ = fmt_spec;
+            _ = options;
+            try stringify(self.value, self.options, writer);
+        }
+    };
+}
+
+test fmt {
+    const expectFmt = std.testing.expectFmt;
+    try expectFmt("123", "{}", .{fmt(@as(u32, 123), .{})});
+    try expectFmt(
+        \\{"num":927,"msg":"hello","sub":{"mybool":true}}
+    , "{}", .{fmt(struct {
+        num: u32,
+        msg: []const u8,
+        sub: struct {
+            mybool: bool,
+        },
+    }{
+        .num = 927,
+        .msg = "hello",
+        .sub = .{ .mybool = true },
+    }, .{})});
+}
lib/std/json.zig
@@ -110,6 +110,9 @@ pub const WriteStream = @import("json/stringify.zig").WriteStream;
 pub const encodeJsonString = @import("json/stringify.zig").encodeJsonString;
 pub const encodeJsonStringChars = @import("json/stringify.zig").encodeJsonStringChars;
 
+pub const Formatter = @import("json/fmt.zig").Formatter;
+pub const fmt = @import("json/fmt.zig").fmt;
+
 // Deprecations
 pub const parse = @compileError("Deprecated; use parseFromSlice() or parseFromTokenSource() instead.");
 pub const parseFree = @compileError("Deprecated; call Parsed(T).deinit() instead.");