API reference
JSON5 in Zig: unquoted keys, single quotes, hex numbers, NaN, and comments.
parseFromSlice reads one JSON5 value into a std.json.Value tree, built
from the same Value, ObjectMap, and Array types as std.json, so a
tree moves between the two parsers. Given a destination type, it decodes
that tree through std.json.parseFromValue. Stringify writes either form
as strict JSON.
Name characters are an approximation: ASCII IdentifierStart and IdentifierPart, plus any non-ASCII code point. The exact ES5.1 categories would need a Unicode property table this package does not vendor.
A \uXXXX escape or a surrogate pair decodes before the check, so
\uD801\uDC00 and U+10400 are the same name character. A lone surrogate
is an error.
A number is .integer when its literal has no fraction and no exponent,
fits i64, and is not a negative zero. Every other number is .float,
including a hexadecimal value past i64. .number_string is never
produced.
A JSON5 value. It is std.json.Value, so the tags, the object map, and
the array are the ones in std.json.
An array of values, the std.json one.
An object's member map, the std.json one. Member order is insertion
order, and a repeated name keeps its first position.
module
Diagnostics
src
Where a parse failed: the bytes, the position, and a message. The caller
owns this struct and passes it in ParseOptions.
Constants
value
.{
.span = .{ .start = 0, .end = 0 },
.line = 1,
.column = 1,
.len = 0,
.buf = undefined,
}The state before a parse writes into it: an empty span at the start of the source, on line 1, column 1, with no message.
Functions
The explanation, for example "a name cannot start with 10".
The bytes live in this struct, so the message stays valid after the parser that made it is gone.
pub fn setMessage(self: *Diagnostics, comptime fmt: []const u8, args: anytype) void
src
Render a message into the diagnostic, truncating on a character boundary when it does not fit.
Types
module
Stringify
src
Writes a std.json.Value as strict JSON. See Stringify.Options.
Constants
Functions
A writer at the start of a document: no indentation, no nesting, and the first value ready.
pub fn beginArray(self: *Stringify) Error!void
src
pub fn beginObject(self: *Stringify) Error!void
src
An alternative to calling write that formats a value with std.fmt.
This function does the usual punctuation and indentation formatting
assuming the resulting formatted string represents a single complete value;
e.g. "1", "[]", "[1,2]", not "1,2".
This function may be useful for doing your own number formatting.
pub fn beginWriteRaw(self: *Stringify) !void
src
An alternative to calling write that allows you to write directly to the .writer field, e.g. with .writer.writeAll().
Call beginWriteRaw(), then write a complete value (including any quotes if necessary) directly to the .writer field,
then call endWriteRaw().
This can be useful for streaming very long strings into the output without needing it all buffered in memory.
pub fn endWriteRaw(self: *Stringify) void
src
See beginWriteRaw.
pub fn objectField(self: *Stringify, key: []const u8) Error!void
src
See Stringify for when to call this method.
key is the string content of the property name.
Surrounding quotes will be added and any special characters will be escaped.
See also objectFieldRaw.
pub fn objectFieldRaw(self: *Stringify, quoted_key: []const u8) Error!void
src
See Stringify for when to call this method.
quoted_key is the complete bytes of the key including quotes and any necessary escape sequences.
A few assertions are performed on the given value to ensure that the caller of this function understands the API contract.
See also objectField.
pub fn beginObjectFieldRaw(self: *Stringify) !void
src
In the rare case that you need to write very long object field names,
this is an alternative to objectField and objectFieldRaw that allows you to write directly to the .writer field
similar to beginWriteRaw.
Call endObjectFieldRaw() when you're done.
pub fn endObjectFieldRaw(self: *Stringify) void
src
See beginObjectFieldRaw.
Renders the given Zig value as JSON.
more
Supported types:
- Zig
bool-> JSONtrueorfalse. - Zig
?T->nullor the rendering ofT. - Zig
i32,u64, etc. -> JSON number or string.- When option
emit_nonportable_numbers_as_stringsis true, if the value is outside the range+-1<<53(the precise integer range of f64), it is rendered as a JSON string in base 10. Otherwise, it is rendered as JSON number.
- When option
- Zig floats -> JSON number or string.
- If the value cannot be precisely represented by an f64, it is rendered as a JSON string. Otherwise, it is rendered as JSON number.
- TODO: Float rendering will likely change in the future, e.g. to remove the unnecessary "e+00".
- Zig
[]const u8,[]u8,*[N]u8,@Vector(N, u8), and similar -> JSON string.- See
Options.emit_strings_as_arrays. - If the content is not valid UTF-8, rendered as an array of numbers instead.
- See
- Zig
[]T,[N]T,*[N]T,@Vector(N, T), and similar -> JSON array of the rendering of each item. - Zig tuple -> JSON array of the rendering of each item.
- Zig
struct-> JSON object with each field in declaration order.- If the struct declares a method
pub fn jsonStringify(self: *@This(), jw: anytype) !void, it is called to do the serialization instead of the default behavior. The givenjwis a pointer to thisStringify. Seestd.json.Valuefor an example. - See
Options.emit_null_optional_fields.
- If the struct declares a method
- Zig
union(enum)-> JSON object with one field named for the active tag and a value representing the payload.- If the payload is
void, then the emitted value is{}. - If the union declares a method
pub fn jsonStringify(self: *@This(), jw: anytype) !void, it is called to do the serialization instead of the default behavior. The givenjwis a pointer to thisStringify.
- If the payload is
- Zig
enum-> JSON string naming the active tag.- If the enum declares a method
pub fn jsonStringify(self: *@This(), jw: anytype) !void, it is called to do the serialization instead of the default behavior. The givenjwis a pointer to thisStringify. - If the enum is non-exhaustive, unnamed values are rendered as integers.
- If the enum declares a method
- Zig untyped enum literal -> JSON string naming the active tag.
- Zig error -> JSON string naming the error.
- Zig
*T-> the rendering ofT. Note there is no guard against circular-reference infinite recursion.
See also alternative functions print and beginWriteRaw.
For writing object field names, use objectField instead.
Writes the given value to the Writer writer.
See Stringify for how the given value is serialized into JSON.
The maximum nesting depth of the output JSON document is 256.
pub fn valueAlloc(gpa: Allocator, v: anytype, options: Options) error{OutOfMemory}![]u8
src
Calls value and stores the result in dynamically allocated memory instead
of taking a writer.
Caller owns returned memory.
pub fn encodeJsonString(string: []const u8, options: Options, writer: *Writer) Error!void
src
Write string to writer as a JSON encoded string.
pub fn encodeJsonStringChars(chars: []const u8, options: Options, writer: *Writer) Error!void
src
Write chars to writer as JSON encoded string characters.
Types
struct
Options
src
Fields
allow_nonfinite: bool = true
false makes NaN and Infinity fail instead of being written as the
JSON5 spelling.
whitespace: enum {
minified,
indent_1,
indent_2,
indent_3,
indent_4,
indent_8,
indent_tab,
} = .minified
Controls the whitespace emitted.
The default .minified is a compact encoding with no whitespace between tokens.
Any setting other than .minified will use newlines, indentation, and a space after each ':'.
.indent_1 means 1 space for each indentation level, .indent_2 means 2 spaces, etc.
.indent_tab uses a tab for each indentation level.
emit_null_optional_fields: bool = true
Should optional fields with null value be written?
emit_strings_as_arrays: bool = false
Arrays/slices of u8 are typically encoded as JSON strings.
This option emits them as arrays of numbers instead.
Does not affect calls to objectField*().
escape_unicode: bool = false
Should unicode characters be escaped in strings?
emit_nonportable_numbers_as_strings: bool = false
When true, renders numbers outside the range +-1<<53 (the precise integer range of f64) as JSON strings in base 10.
pub const ParseError = Allocator.Error || std.json.ParseFromValueError || error{SyntaxError}
src
What a parse can return: the source breaks the grammar, the allocator
failed, or the typed pass rejected the tree. On error.SyntaxError,
options.diagnostics says where.
struct
ParseOptions
src
How to parse a document.
Fields
diagnostics: ?*Diagnostics = null
Filled on error.SyntaxError. Untouched when the parse succeeds, and
on error.OutOfMemory. Null means the caller wants only the error.
json: std.json.ParseOptions = .{}
The std.json options, used when T is not std.json.Value:
duplicate fields, unknown fields, string allocation, and numbers.
type fn
Parsed
src
pub fn Parsed(comptime T: type) type
A parsed value and the memory that holds it.
Fields
arena: *ArenaAllocator
The arena that owns every string, object, and array in value.
It is heap-allocated on purpose. std.json.Array is a managed list
that carries the allocator it was built with, and that allocator's
pointer is this arena. A value field would move with Parsed, and
every array in the tree would point at a dead stack slot.
value: T
The root value.
Functions
Free the arena and everything the value points at. Takes self by
value, like std.json.Parsed.
pub fn parseFromSlice(
comptime T: type,
allocator: Allocator,
source: []const u8,
options: ParseOptions,
) ParseError!Parsed(T)
src
Parse one JSON5 document into T.
more
T is any type std.json.parseFromValue accepts: a struct, a union, an
enum, a slice, or std.json.Value for the tree. Every string, object, and
array the value points at is copied into an arena that the returned
Parsed owns, so the source may be freed as soon as this returns.
When T is std.json.Value, the tree comes back as it was parsed. For
anything else, the parser builds the tree first and std.json turns it
into T with options.json. A document that breaks the grammar is
error.SyntaxError, and options.diagnostics says where.
pub fn parseFromSliceLeaky(
comptime T: type,
allocator: Allocator,
source: []const u8,
options: ParseOptions,
) ParseError!T
src
Parse one JSON5 document into T, in memory the caller already owns.
more
Use this when the caller has an arena whose lifetime is known, such as a
request or a configuration load. The returned value owns nothing, and
freeing it is the caller's problem. The source is still copied, so it may
be freed as soon as this returns. The arena must stay at the same address
while the value lives, because a std.json.Value tree's arrays hold the
allocator built from it.