diff options
Diffstat (limited to 'src/jv/value.zig')
| -rw-r--r-- | src/jv/value.zig | 160 |
1 files changed, 157 insertions, 3 deletions
diff --git a/src/jv/value.zig b/src/jv/value.zig index 6a4c4b3..ffdec44 100644 --- a/src/jv/value.zig +++ b/src/jv/value.zig @@ -1,5 +1,159 @@ const std = @import("std"); +const Allocator = std.mem.Allocator; -pub const Value = std.json.Value; -pub const Array = std.json.Array; -pub const Object = std.json.ObjectMap; +pub const Value = struct { + const _Internal = std.json.Value; + _internal: _Internal, + + pub const Kind = enum { null, bool, integer, float, string, array, object, number_string }; + + pub fn kind(self: Value) Kind { + return switch (self._internal) { + .null => .null, + .bool => .bool, + .integer => .integer, + .float => .float, + .string => .string, + .array => .array, + .object => .object, + .number_string => .number_string, + }; + } + + pub const @"null": Value = .{ ._internal = .null }; + pub const @"true": Value = .{ ._internal = .{ .bool = true } }; + pub const @"false": Value = .{ ._internal = .{ .bool = false } }; + + pub fn initBool(b: bool) Value { + return .{ ._internal = .{ .bool = b } }; + } + + pub fn initInteger(i: i64) Value { + return .{ ._internal = .{ .integer = i } }; + } + + pub fn initFloat(f: f64) Value { + return .{ ._internal = .{ .float = f } }; + } + + pub fn initString(s: []const u8) Value { + return .{ ._internal = .{ .string = s } }; + } + + pub fn initArray(arr: Array) Value { + return .{ ._internal = .{ .array = arr._internal } }; + } + + pub fn initObject(obj: Object) Value { + return .{ ._internal = .{ .object = obj._internal } }; + } + + pub fn deinit(self: *Value, allocator: Allocator) void { + switch (self._internal) { + .string => |s| allocator.free(s), + .array => |*a| a.deinit(), + .object => |*o| o.deinit(), + else => {}, + } + } + + pub fn boolean(self: Value) bool { + return self._internal.bool; + } + + pub fn integer(self: Value) i64 { + return self._internal.integer; + } + + pub fn float(self: Value) f64 { + return self._internal.float; + } + + pub fn string(self: Value) []const u8 { + return self._internal.string; + } + + pub fn array(self: Value) Array { + return .{ ._internal = self._internal.array }; + } + + pub fn object(self: Value) Object { + return .{ ._internal = self._internal.object }; + } + + pub fn arrayGet(self: Value, idx: usize) Value { + const items = self._internal.array.items; + if (idx < items.len) { + return .{ ._internal = items[idx] }; + } + return Value.null; + } + + pub fn arrayLen(self: Value) usize { + return self._internal.array.items.len; + } + + pub fn arrayAppend(self: *Value, item: Value) !void { + try self._internal.array.append(item._internal); + } + + pub fn objectGet(self: Value, key: []const u8) ?Value { + if (self._internal.object.get(key)) |v| { + return .{ ._internal = v }; + } + return null; + } + + pub fn objectSet(self: *Value, key: []const u8, val: Value) !void { + try self._internal.object.put(key, val._internal); + } +}; + +pub const Array = struct { + const _Internal = std.json.Array; + _internal: _Internal, + + pub fn init(allocator: Allocator) Array { + return .{ ._internal = _Internal.init(allocator) }; + } + + pub fn deinit(self: *Array) void { + self._internal.deinit(); + } + + pub fn get(self: Array, idx: usize) Value { + return .{ ._internal = self._internal.items[idx] }; + } + + pub fn len(self: Array) usize { + return self._internal.items.len; + } + + pub fn append(self: *Array, value: Value) !void { + try self._internal.append(value._internal); + } +}; + +pub const Object = struct { + const _Internal = std.json.ObjectMap; + _internal: _Internal, + + pub fn init(allocator: Allocator) Object { + return .{ ._internal = _Internal.init(allocator) }; + } + + pub fn deinit(self: *Object) void { + self._internal.deinit(); + } + + pub fn get(self: Object, key: []const u8) ?Value { + if (self._internal.get(key)) |v| { + return .{ ._internal = v }; + } + return null; + } + + pub fn set(self: *Object, key: []const u8, value: Value) !void { + try self._internal.put(key, value._internal); + } +}; |
