diff --git a/lib/std/json.zig b/lib/std/json.zig index 29f46c263a..aa75d892da 100644 --- a/lib/std/json.zig +++ b/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."); diff --git a/lib/std/json/fmt.zig b/lib/std/json/fmt.zig new file mode 100644 index 0000000000..09f58b3be6 --- /dev/null +++ b/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 }, + }, .{})}); +}