tiny.pluck.toplevel.json
Defined in toplevel.
API (4)
Actions
Public operations.
Types and contracts
Public types and contracts.
Source
Source: lib/pluck/src/toplevel/json.zig
zig
const std = @import("std");const pretty = @import("pretty");const result_owner = @import("result.zig");const top_types = @import("types.zig");const QueryResult = result_owner.QueryResult;const QueryOutcome = top_types.QueryOutcome;const Span = top_types.SourceSpan;const pretty_json = pretty.json;pub fn writeQueryResult(result: *const QueryResult, writer: anytype) !void { var stream = pretty_json.Writer.init(writer, .minified); const object = try stream.object(); try writeQueryResultFields(result, object); try object.endLine();}pub fn writeQueryResultFields(result: *const QueryResult, object: pretty_json.Object) !void { const status: []const u8 = if (result.program_error) "error" else if (result.limit_reason != null) "partial" else if (result.outcomes.len == 0) "error" else "success"; const outcomes = try object.array("outcomes"); for (result.outcomes) |outcome| { const outcome_object = try outcomes.object(); try outcome_object.field("value", outcome.value_str); try outcome_object.print("probability", "{d}", .{outcome.probability}); try outcome_object.end(); } try outcomes.end(); const stats = try object.object("stats"); try stats.field("time_ns", result.stats.time_ns); try stats.field("wmc_time_ns", result.stats.wmc_time_ns); try stats.field("refinement_time_ns", result.stats.refinement_time_ns); try stats.field("refinement_count", result.stats.refinement_count); if (result.stats.num_forward_calls > 0) { try stats.field("forward_calls", result.stats.num_forward_calls); } if (result.stats.num_recursive_calls > 0) { try stats.field("recursive_calls", result.stats.num_recursive_calls); } if (result.stats.variable_count > 0) { try stats.field("bdd_variables", result.stats.variable_count); } if (result.stats.node_count > 0) { try stats.field("bdd_nodes", result.stats.node_count); } const total_cache = result.stats.ite_cache_hits + result.stats.ite_cache_misses; if (total_cache > 0) { try stats.field("ite_cache_hits", result.stats.ite_cache_hits); try stats.field("ite_cache_misses", result.stats.ite_cache_misses); } if (result.stats.unique_table_grows > 0) { try stats.field("bdd_unique_table_grows", result.stats.unique_table_grows); } if (result.stats.ite_cache_grows > 0) { try stats.field("ite_cache_grows", result.stats.ite_cache_grows); } const total_thunks = result.stats.thunk_reuse_hits + result.stats.thunk_reuse_misses; if (total_thunks > 0) { try stats.field("thunk_reuse_hits", result.stats.thunk_reuse_hits); try stats.field("thunk_reuse_misses", result.stats.thunk_reuse_misses); } if (result.stats.thunk_evaluations > 0) { try stats.field("thunk_evaluations", result.stats.thunk_evaluations); try stats.field("thunk_cache_hits", result.stats.thunk_cache_hits); } if (result.stats.bdd_samples_len > 0) { const samples = try stats.array("bdd_samples"); var i: usize = 0; while (i < @as(usize, result.stats.bdd_samples_len)) : (i += 1) { const sample = try samples.object(); try sample.field("forward_calls", result.stats.bdd_samples_forward_calls[i]); try sample.field("bdd_variables", result.stats.bdd_samples_vars[i]); try sample.field("bdd_nodes", result.stats.bdd_samples_nodes[i]); try sample.end(); } try samples.end(); } try stats.end(); try object.field("program_error", result.program_error); if (result.limit_reason) |reason| { try object.field("limit_reason", @tagName(reason)); } try object.field("status", status);}pub const JsonError = struct { type: []const u8, message: []const u8, file: ?[]const u8 = null, span: ?Span = null, pub fn write(self: JsonError, writer: anytype) !void { var stream = pretty_json.Writer.init(writer, .minified); const object = try stream.object(); try object.field("type", self.type); try object.field("message", self.message); if (self.file) |f| { try object.field("file", f); } if (self.span) |s| { const span = try object.object("span"); const start = try span.object("start"); try start.field("line", s.start.line); try start.field("column", s.start.column); try start.field("offset", s.start.offset); try start.end(); const end = try span.object("end"); try end.field("line", s.end.line); try end.field("column", s.end.column); try end.field("offset", s.end.offset); try end.end(); try span.end(); } try object.endLine(); }};test "writeQueryResult includes bdd stats and samples" { const allocator = std.testing.allocator; const outcomes = try allocator.alloc(QueryOutcome, 1); outcomes[0] = .{ .value_str = try allocator.dupe(u8, "True"), .probability = 0.5, }; var result = QueryResult{ .outcomes = outcomes, .stats = .{ .time_ns = 123, .wmc_time_ns = 100, .refinement_time_ns = 50, .refinement_count = 2, .num_forward_calls = 4, .num_recursive_calls = 8, .variable_count = 3, .node_count = 10, .ite_cache_hits = 5, .ite_cache_misses = 2, .bdd_samples_len = 1, }, .limit_reason = null, .program_error = false, .allocator = allocator, }; result.stats.bdd_samples_forward_calls[0] = 4; result.stats.bdd_samples_vars[0] = 3; result.stats.bdd_samples_nodes[0] = 10; defer result.deinit(); var out_buf: [1024]u8 = undefined; var out_stream = std.Io.Writer.fixed(&out_buf); try writeQueryResult(&result, &out_stream); const written = out_stream.buffered(); try std.testing.expect(std.mem.indexOf(u8, written, "\"wmc_time_ns\":100") != null); try std.testing.expect(std.mem.indexOf(u8, written, "\"bdd_nodes\":10") != null); try std.testing.expect(std.mem.indexOf(u8, written, "\"bdd_samples\"") != null);}test "writeQueryResult includes program_error and limit_reason fields" { const allocator = std.testing.allocator; const outcomes = try allocator.alloc(QueryOutcome, 1); outcomes[0] = .{ .value_str = try allocator.dupe(u8, "True"), .probability = 1.0, }; var result = QueryResult{ .outcomes = outcomes, .stats = .{}, .limit_reason = .factor_weight_too_complex, .program_error = false, .allocator = allocator, }; defer result.deinit(); var out_buf: [1024]u8 = undefined; var out_stream = std.Io.Writer.fixed(&out_buf); try writeQueryResult(&result, &out_stream); const written = out_stream.buffered(); try std.testing.expect(std.mem.indexOf(u8, written, "\"program_error\":false") != null); try std.testing.expect(std.mem.indexOf(u8, written, "\"limit_reason\":\"factor_weight_too_complex\"") != null); try std.testing.expect(std.mem.indexOf(u8, written, "\"status\":\"partial\"") != null);}test "JsonError includes span when present" { var buf: [512]u8 = undefined; var writer = std.Io.Writer.fixed(&buf); const span = Span{ .start = .{ .line = 0, .column = 1, .offset = 2 }, .end = .{ .line = 0, .column = 2, .offset = 3 }, }; const err = JsonError{ .type = "eval_error", .message = "oops\n\"quoted\"", .span = span, }; try err.write(&writer); try std.testing.expectEqualStrings( "{\"type\":\"eval_error\",\"message\":\"oops\\n\\\"quoted\\\"\",\"span\":{\"start\":{\"line\":0,\"column\":1,\"offset\":2},\"end\":{\"line\":0,\"column\":2,\"offset\":3}}}\n", writer.buffered(), );}Source: lib/pluck/src/toplevel/root.zig:3
zig
pub const json = @import("json.zig");Audit
| Definitions | 5 |
|---|---|
| Public names | 9 |
| Members | 4 |
| Version | 26.7.0 |
| Revision | daab053ee433 |