mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
std: Support user-provided jsonParse method. Unify json.Parser and json.parse* (#15705)
This commit is contained in:
+66
-7
@@ -1,19 +1,73 @@
|
||||
//! JSON parsing and stringification conforming to RFC 8259. https://datatracker.ietf.org/doc/html/rfc8259
|
||||
//!
|
||||
//! The low-level `Scanner` API reads from an input slice or successive slices of inputs,
|
||||
//! The low-level `Scanner` API produces `Token`s from an input slice or successive slices of inputs,
|
||||
//! The `Reader` API connects a `std.io.Reader` to a `Scanner`.
|
||||
//!
|
||||
//! The high-level `parseFromSlice` and `parseFromTokenSource` deserializes a JSON document into a Zig type.
|
||||
//! The high-level `Parser` parses any JSON document into a dynamically typed `ValueTree` that has its own memory arena.
|
||||
//! The high-level `parseFromSlice` and `parseFromTokenSource` deserialize a JSON document into a Zig type.
|
||||
//! Parse into a dynamically-typed `Value` to load any JSON value for runtime inspection.
|
||||
//!
|
||||
//! The low-level `writeStream` emits syntax-conformant JSON tokens to a `std.io.Writer`.
|
||||
//! The high-level `stringify` serializes a Zig type into JSON.
|
||||
//! The high-level `stringify` serializes a Zig or `Value` type into JSON.
|
||||
|
||||
const testing = @import("std").testing;
|
||||
const ArrayList = @import("std").ArrayList;
|
||||
|
||||
test Scanner {
|
||||
var scanner = Scanner.initCompleteInput(testing.allocator, "{\"foo\": 123}\n");
|
||||
defer scanner.deinit();
|
||||
try testing.expectEqual(Token.object_begin, try scanner.next());
|
||||
try testing.expectEqualSlices(u8, "foo", (try scanner.next()).string);
|
||||
try testing.expectEqualSlices(u8, "123", (try scanner.next()).number);
|
||||
try testing.expectEqual(Token.object_end, try scanner.next());
|
||||
try testing.expectEqual(Token.end_of_document, try scanner.next());
|
||||
}
|
||||
|
||||
test parseFromSlice {
|
||||
var parsed_str = try parseFromSlice([]const u8, testing.allocator, "\"a\\u0020b\"", .{});
|
||||
defer parsed_str.deinit();
|
||||
try testing.expectEqualSlices(u8, "a b", parsed_str.value);
|
||||
|
||||
const T = struct { a: i32 = -1, b: [2]u8 };
|
||||
var parsed_struct = try parseFromSlice(T, testing.allocator, "{\"b\":\"xy\"}", .{});
|
||||
defer parsed_struct.deinit();
|
||||
try testing.expectEqual(@as(i32, -1), parsed_struct.value.a); // default value
|
||||
try testing.expectEqualSlices(u8, "xy", parsed_struct.value.b[0..]);
|
||||
}
|
||||
|
||||
test Value {
|
||||
var parsed = try parseFromSlice(Value, testing.allocator, "{\"anything\": \"goes\"}", .{});
|
||||
defer parsed.deinit();
|
||||
try testing.expectEqualSlices(u8, "goes", parsed.value.object.get("anything").?.string);
|
||||
}
|
||||
|
||||
test writeStream {
|
||||
var out = ArrayList(u8).init(testing.allocator);
|
||||
defer out.deinit();
|
||||
var write_stream = writeStream(out.writer(), 99);
|
||||
try write_stream.beginObject();
|
||||
try write_stream.objectField("foo");
|
||||
try write_stream.emitNumber(123);
|
||||
try write_stream.endObject();
|
||||
const expected =
|
||||
\\{
|
||||
\\ "foo": 123
|
||||
\\}
|
||||
;
|
||||
try testing.expectEqualSlices(u8, expected, out.items);
|
||||
}
|
||||
|
||||
test stringify {
|
||||
var out = ArrayList(u8).init(testing.allocator);
|
||||
defer out.deinit();
|
||||
|
||||
const T = struct { a: i32, b: []const u8 };
|
||||
try stringify(T{ .a = 123, .b = "xy" }, .{}, out.writer());
|
||||
try testing.expectEqualSlices(u8, "{\"a\":123,\"b\":\"xy\"}", out.items);
|
||||
}
|
||||
|
||||
pub const ValueTree = @import("json/dynamic.zig").ValueTree;
|
||||
pub const ObjectMap = @import("json/dynamic.zig").ObjectMap;
|
||||
pub const Array = @import("json/dynamic.zig").Array;
|
||||
pub const Value = @import("json/dynamic.zig").Value;
|
||||
pub const Parser = @import("json/dynamic.zig").Parser;
|
||||
|
||||
pub const validate = @import("json/scanner.zig").validate;
|
||||
pub const Error = @import("json/scanner.zig").Error;
|
||||
@@ -30,9 +84,11 @@ pub const isNumberFormattedLikeAnInteger = @import("json/scanner.zig").isNumberF
|
||||
|
||||
pub const ParseOptions = @import("json/static.zig").ParseOptions;
|
||||
pub const parseFromSlice = @import("json/static.zig").parseFromSlice;
|
||||
pub const parseFromSliceLeaky = @import("json/static.zig").parseFromSliceLeaky;
|
||||
pub const parseFromTokenSource = @import("json/static.zig").parseFromTokenSource;
|
||||
pub const parseFromTokenSourceLeaky = @import("json/static.zig").parseFromTokenSourceLeaky;
|
||||
pub const ParseError = @import("json/static.zig").ParseError;
|
||||
pub const parseFree = @import("json/static.zig").parseFree;
|
||||
pub const Parsed = @import("json/static.zig").Parsed;
|
||||
|
||||
pub const StringifyOptions = @import("json/stringify.zig").StringifyOptions;
|
||||
pub const encodeJsonString = @import("json/stringify.zig").encodeJsonString;
|
||||
@@ -45,6 +101,9 @@ pub const writeStream = @import("json/write_stream.zig").writeStream;
|
||||
|
||||
// Deprecations
|
||||
pub const parse = @compileError("Deprecated; use parseFromSlice() or parseFromTokenSource() instead.");
|
||||
pub const parseFree = @compileError("Deprecated; call Parsed(T).deinit() instead.");
|
||||
pub const Parser = @compileError("Deprecated; use parseFromSlice(Value) or parseFromTokenSource(Value) instead.");
|
||||
pub const ValueTree = @compileError("Deprecated; use Parsed(Value) instead.");
|
||||
pub const StreamingParser = @compileError("Deprecated; use json.Scanner or json.Reader instead.");
|
||||
pub const TokenStream = @compileError("Deprecated; use json.Scanner or json.Reader instead.");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user