unionstd.json.dynamic.Value[src]

Represents any JSON value, potentially containing other JSON values. A .float value may be an approximation of the original value. Arbitrary precision numbers can be represented by .number_string values. See also std.json.ParseOptions.parse_numbers.

Fields

null
bool: bool
integer: i64
float: f64
number_string: []const u8
string: []const u8
array: Array
object: ObjectMap

Functions

FunctionparseFromNumberSlice[src]

pub fn parseFromNumberSlice(s: []const u8) Value

Parameters

s: []const u8

Source Code

Source code
pub fn parseFromNumberSlice(s: []const u8) Value {
    if (!isNumberFormattedLikeAnInteger(s)) {
        const f = std.fmt.parseFloat(f64, s) catch unreachable;
        if (std.math.isFinite(f)) {
            return Value{ .float = f };
        } else {
            return Value{ .number_string = s };
        }
    }
    if (std.fmt.parseInt(i64, s, 10)) |i| {
        return Value{ .integer = i };
    } else |e| {
        switch (e) {
            error.Overflow => return Value{ .number_string = s },
            error.InvalidCharacter => unreachable,
        }
    }
}

Functiondump[src]

pub fn dump(self: Value) void

Parameters

self: Value

Source Code

Source code
pub fn dump(self: Value) void {
    std.debug.lockStdErr();
    defer std.debug.unlockStdErr();

    const stderr = std.io.getStdErr().writer();
    stringify(self, .{}, stderr) catch return;
}

FunctionjsonStringify[src]

pub fn jsonStringify(value: @This(), jws: anytype) !void

Parameters

value: @This()

Source Code

Source code
pub fn jsonStringify(value: @This(), jws: anytype) !void {
    switch (value) {
        .null => try jws.write(null),
        .bool => |inner| try jws.write(inner),
        .integer => |inner| try jws.write(inner),
        .float => |inner| try jws.write(inner),
        .number_string => |inner| try jws.print("{s}", .{inner}),
        .string => |inner| try jws.write(inner),
        .array => |inner| try jws.write(inner.items),
        .object => |inner| {
            try jws.beginObject();
            var it = inner.iterator();
            while (it.next()) |entry| {
                try jws.objectField(entry.key_ptr.*);
                try jws.write(entry.value_ptr.*);
            }
            try jws.endObject();
        },
    }
}

FunctionjsonParse[src]

pub fn jsonParse(allocator: Allocator, source: anytype, options: ParseOptions) ParseError(@TypeOf(source.*))!@This()

Parameters

allocator: Allocator
options: ParseOptions

Source Code

Source code
pub fn jsonParse(allocator: Allocator, source: anytype, options: ParseOptions) ParseError(@TypeOf(source.*))!@This() {
    // The grammar of the stack is:
    //  (.array | .object .string)*
    var stack = Array.init(allocator);
    defer stack.deinit();

    while (true) {
        // Assert the stack grammar at the top of the stack.
        debug.assert(stack.items.len == 0 or
            stack.items[stack.items.len - 1] == .array or
            (stack.items[stack.items.len - 2] == .object and stack.items[stack.items.len - 1] == .string));

        switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) {
            .allocated_string => |s| {
                return try handleCompleteValue(&stack, allocator, source, Value{ .string = s }, options) orelse continue;
            },
            .allocated_number => |slice| {
                if (options.parse_numbers) {
                    return try handleCompleteValue(&stack, allocator, source, Value.parseFromNumberSlice(slice), options) orelse continue;
                } else {
                    return try handleCompleteValue(&stack, allocator, source, Value{ .number_string = slice }, options) orelse continue;
                }
            },

            .null => return try handleCompleteValue(&stack, allocator, source, .null, options) orelse continue,
            .true => return try handleCompleteValue(&stack, allocator, source, Value{ .bool = true }, options) orelse continue,
            .false => return try handleCompleteValue(&stack, allocator, source, Value{ .bool = false }, options) orelse continue,

            .object_begin => {
                switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) {
                    .object_end => return try handleCompleteValue(&stack, allocator, source, Value{ .object = ObjectMap.init(allocator) }, options) orelse continue,
                    .allocated_string => |key| {
                        try stack.appendSlice(&[_]Value{
                            Value{ .object = ObjectMap.init(allocator) },
                            Value{ .string = key },
                        });
                    },
                    else => unreachable,
                }
            },
            .array_begin => {
                try stack.append(Value{ .array = Array.init(allocator) });
            },
            .array_end => return try handleCompleteValue(&stack, allocator, source, stack.pop().?, options) orelse continue,

            else => unreachable,
        }
    }
}

FunctionjsonParseFromValue[src]

pub fn jsonParseFromValue(allocator: Allocator, source: Value, options: ParseOptions) !@This()

Parameters

allocator: Allocator
source: Value
options: ParseOptions

Source Code

Source code
pub fn jsonParseFromValue(allocator: Allocator, source: Value, options: ParseOptions) !@This() {
    _ = allocator;
    _ = options;
    return source;
}

Source Code

Source code
pub const Value = union(enum) {
    null,
    bool: bool,
    integer: i64,
    float: f64,
    number_string: []const u8,
    string: []const u8,
    array: Array,
    object: ObjectMap,

    pub fn parseFromNumberSlice(s: []const u8) Value {
        if (!isNumberFormattedLikeAnInteger(s)) {
            const f = std.fmt.parseFloat(f64, s) catch unreachable;
            if (std.math.isFinite(f)) {
                return Value{ .float = f };
            } else {
                return Value{ .number_string = s };
            }
        }
        if (std.fmt.parseInt(i64, s, 10)) |i| {
            return Value{ .integer = i };
        } else |e| {
            switch (e) {
                error.Overflow => return Value{ .number_string = s },
                error.InvalidCharacter => unreachable,
            }
        }
    }

    pub fn dump(self: Value) void {
        std.debug.lockStdErr();
        defer std.debug.unlockStdErr();

        const stderr = std.io.getStdErr().writer();
        stringify(self, .{}, stderr) catch return;
    }

    pub fn jsonStringify(value: @This(), jws: anytype) !void {
        switch (value) {
            .null => try jws.write(null),
            .bool => |inner| try jws.write(inner),
            .integer => |inner| try jws.write(inner),
            .float => |inner| try jws.write(inner),
            .number_string => |inner| try jws.print("{s}", .{inner}),
            .string => |inner| try jws.write(inner),
            .array => |inner| try jws.write(inner.items),
            .object => |inner| {
                try jws.beginObject();
                var it = inner.iterator();
                while (it.next()) |entry| {
                    try jws.objectField(entry.key_ptr.*);
                    try jws.write(entry.value_ptr.*);
                }
                try jws.endObject();
            },
        }
    }

    pub fn jsonParse(allocator: Allocator, source: anytype, options: ParseOptions) ParseError(@TypeOf(source.*))!@This() {
        // The grammar of the stack is:
        //  (.array | .object .string)*
        var stack = Array.init(allocator);
        defer stack.deinit();

        while (true) {
            // Assert the stack grammar at the top of the stack.
            debug.assert(stack.items.len == 0 or
                stack.items[stack.items.len - 1] == .array or
                (stack.items[stack.items.len - 2] == .object and stack.items[stack.items.len - 1] == .string));

            switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) {
                .allocated_string => |s| {
                    return try handleCompleteValue(&stack, allocator, source, Value{ .string = s }, options) orelse continue;
                },
                .allocated_number => |slice| {
                    if (options.parse_numbers) {
                        return try handleCompleteValue(&stack, allocator, source, Value.parseFromNumberSlice(slice), options) orelse continue;
                    } else {
                        return try handleCompleteValue(&stack, allocator, source, Value{ .number_string = slice }, options) orelse continue;
                    }
                },

                .null => return try handleCompleteValue(&stack, allocator, source, .null, options) orelse continue,
                .true => return try handleCompleteValue(&stack, allocator, source, Value{ .bool = true }, options) orelse continue,
                .false => return try handleCompleteValue(&stack, allocator, source, Value{ .bool = false }, options) orelse continue,

                .object_begin => {
                    switch (try source.nextAllocMax(allocator, .alloc_always, options.max_value_len.?)) {
                        .object_end => return try handleCompleteValue(&stack, allocator, source, Value{ .object = ObjectMap.init(allocator) }, options) orelse continue,
                        .allocated_string => |key| {
                            try stack.appendSlice(&[_]Value{
                                Value{ .object = ObjectMap.init(allocator) },
                                Value{ .string = key },
                            });
                        },
                        else => unreachable,
                    }
                },
                .array_begin => {
                    try stack.append(Value{ .array = Array.init(allocator) });
                },
                .array_end => return try handleCompleteValue(&stack, allocator, source, stack.pop().?, options) orelse continue,

                else => unreachable,
            }
        }
    }

    pub fn jsonParseFromValue(allocator: Allocator, source: Value, options: ParseOptions) !@This() {
        _ = allocator;
        _ = options;
        return source;
    }
}