Add functions to print and to convert to string
This commit is contained in:
parent
5357d0a593
commit
438e800f2f
280
src/json.zig
280
src/json.zig
@ -1,4 +1,5 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
pub const JSONError = error{
|
pub const JSONError = error{
|
||||||
IncorrectType,
|
IncorrectType,
|
||||||
@ -16,17 +17,43 @@ pub const JSONType = enum {
|
|||||||
Null,
|
Null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const JSONFormat = struct {
|
||||||
|
indent_level: usize = 4,
|
||||||
|
indent_char: u8 = ' ',
|
||||||
|
one_line: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn printIndent(writer: std.fs.File.Writer, format: JSONFormat, level: usize) !void {
|
||||||
|
if (!format.one_line) {
|
||||||
|
try writer.writeByte('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0..level) |_| {
|
||||||
|
try writer.writeByteNTimes(format.indent_char, format.indent_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn indentString(allocator: std.mem.Allocator, format: JSONFormat, level: usize) ![]const u8 {
|
||||||
|
var str = std.ArrayList(u8).init(allocator);
|
||||||
|
|
||||||
|
if (!format.one_line) {
|
||||||
|
try str.append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (0..level) |_| {
|
||||||
|
try str.appendNTimes(format.indent_char, format.indent_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return try str.toOwnedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
pub const JSONObject = struct {
|
pub const JSONObject = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
children: MapType,
|
children: MapType,
|
||||||
|
|
||||||
const MapType = std.StringHashMap(*JSONValue);
|
const MapType = std.StringHashMap(*JSONValue);
|
||||||
|
|
||||||
pub fn get(self: *JSONObject, name: []const u8) ?*JSONValue {
|
pub fn create(allocator: std.mem.Allocator) JSONError!*JSONObject {
|
||||||
return self.children.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator) JSONError!*JSONObject {
|
|
||||||
var self = try allocator.create(JSONObject);
|
var self = try allocator.create(JSONObject);
|
||||||
self.allocator = allocator;
|
self.allocator = allocator;
|
||||||
self.children = MapType.init(allocator);
|
self.children = MapType.init(allocator);
|
||||||
@ -34,6 +61,59 @@ pub const JSONObject = struct {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(self: *JSONObject, name: []const u8) ?*JSONValue {
|
||||||
|
return self.children.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print(self: *JSONObject, writer: std.fs.File.Writer, format: JSONFormat, indent_level: usize) std.fs.File.WriteError!void {
|
||||||
|
try writer.writeByte('{');
|
||||||
|
|
||||||
|
var iter = self.children.keyIterator();
|
||||||
|
var first = true;
|
||||||
|
while (iter.next()) |key| {
|
||||||
|
if (!first) {
|
||||||
|
try writer.writeAll(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
try printIndent(writer, format, indent_level + 1);
|
||||||
|
try writer.print("\"{s}\": ", .{key.*});
|
||||||
|
|
||||||
|
try self.children.get(key.*).?.print(writer, format, indent_level + 1);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try printIndent(writer, format, indent_level);
|
||||||
|
try writer.writeByte('}');
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toString(self: *JSONObject, allocator: std.mem.Allocator, format: JSONFormat, indent_level: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
var str = std.ArrayList(u8).init(allocator);
|
||||||
|
try str.append('{');
|
||||||
|
|
||||||
|
var iter = self.children.keyIterator();
|
||||||
|
var first = true;
|
||||||
|
while (iter.next()) |key| {
|
||||||
|
if (!first) {
|
||||||
|
try str.appendSlice(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
try str.appendSlice(try indentString(allocator, format, indent_level + 1));
|
||||||
|
try str.append('"');
|
||||||
|
try str.appendSlice(key.*);
|
||||||
|
try str.appendSlice("\": ");
|
||||||
|
|
||||||
|
const valstr = try self.children.get(key.*).?.toString(allocator, format, indent_level + 1);
|
||||||
|
defer allocator.free(valstr);
|
||||||
|
try str.appendSlice(valstr);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try str.appendSlice(try indentString(allocator, format, indent_level));
|
||||||
|
try str.append('}');
|
||||||
|
|
||||||
|
return try str.toOwnedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *JSONObject) void {
|
pub fn deinit(self: *JSONObject) void {
|
||||||
var iter = self.children.valueIterator();
|
var iter = self.children.valueIterator();
|
||||||
while (iter.next()) |child| {
|
while (iter.next()) |child| {
|
||||||
@ -41,9 +121,10 @@ pub const JSONObject = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var names = self.children.keyIterator();
|
var names = self.children.keyIterator();
|
||||||
while (names.next()) |name| {
|
while (names.next()) |key| {
|
||||||
self.allocator.free(name.*);
|
self.allocator.free(key.*);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.children.deinit();
|
self.children.deinit();
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
@ -63,6 +144,9 @@ pub const JSONValue = struct {
|
|||||||
getBool: *const fn (self: *const JSONValue) JSONError!bool = incorrectValue(bool),
|
getBool: *const fn (self: *const JSONValue) JSONError!bool = incorrectValue(bool),
|
||||||
|
|
||||||
deinit: *const fn (self: *JSONValue) void,
|
deinit: *const fn (self: *JSONValue) void,
|
||||||
|
|
||||||
|
print: *const fn (self: *const JSONValue, writer: std.fs.File.Writer, format: JSONFormat, indent_level: usize) std.fs.File.WriteError!void,
|
||||||
|
toString: *const fn (self: *const JSONValue, allocator: std.mem.Allocator, format: JSONFormat, indent_level: usize) std.mem.Allocator.Error![]const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn incorrectValue(comptime T: type) *const fn (*const JSONValue) JSONError!T {
|
fn incorrectValue(comptime T: type) *const fn (*const JSONValue) JSONError!T {
|
||||||
@ -97,34 +181,50 @@ pub const JSONValue = struct {
|
|||||||
return self.vtable.getObject(self);
|
return self.vtable.getObject(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print(self: *const JSONValue, writer: std.fs.File.Writer, format: JSONFormat, indent_level: usize) std.fs.File.WriteError!void {
|
||||||
|
return self.vtable.print(self, writer, format, indent_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toString(self: *const JSONValue, allocator: std.mem.Allocator, format: JSONFormat, indent_level: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
return self.vtable.toString(self, allocator, format, indent_level);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *JSONValue) void {
|
pub fn deinit(self: *JSONValue) void {
|
||||||
self.vtable.deinit(self);
|
self.vtable.deinit(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createNull(allocator: std.mem.Allocator) JSONError!*JSONValue {
|
pub fn createNull(allocator: std.mem.Allocator) JSONError!*JSONValue {
|
||||||
var self = try allocator.create(JSONValue);
|
var self = try allocator.create(JSONValue);
|
||||||
self.type = .Null;
|
self.type = .Null;
|
||||||
self.vtable = .{ .deinit = basicDeinit };
|
self.vtable = .{ .deinit = basicDeinit, .print = printNull, .toString = toStringNull };
|
||||||
self.allocator = allocator;
|
self.allocator = allocator;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn printNull(_: *const JSONValue, writer: std.fs.File.Writer, _: JSONFormat, _: usize) std.fs.File.WriteError!void {
|
||||||
|
return writer.writeAll("null");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toStringNull(_: *const JSONValue, allocator: std.mem.Allocator, _: JSONFormat, _: usize) ![]const u8 {
|
||||||
|
return allocator.dupe(u8, "null");
|
||||||
|
}
|
||||||
|
|
||||||
fn basicDeinit(self: *JSONValue) void {
|
fn basicDeinit(self: *JSONValue) void {
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSONArrayValue = struct {
|
pub const JSONArrayValue = struct {
|
||||||
value: JSONValue,
|
value: JSONValue,
|
||||||
array: []*JSONValue,
|
array: []*JSONValue,
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator, array: []*JSONValue) !*JSONValue {
|
pub fn create(allocator: std.mem.Allocator, array: []*JSONValue) !*JSONValue {
|
||||||
var self = try allocator.create(JSONArrayValue);
|
var self = try allocator.create(JSONArrayValue);
|
||||||
self.array = array;
|
self.array = array;
|
||||||
self.value = .{
|
self.value = .{
|
||||||
.type = .Array,
|
.type = .Array,
|
||||||
.vtable = .{ .getArray = getValue, .deinit = deinit },
|
.vtable = .{ .getArray = getValue, .print = print, .toString = toString, .deinit = deinit },
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -136,6 +236,47 @@ const JSONArrayValue = struct {
|
|||||||
return self.array;
|
return self.array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print(value: *const JSONValue, writer: std.fs.File.Writer, format: JSONFormat, indent_level: usize) std.fs.File.WriteError!void {
|
||||||
|
const self: *const JSONArrayValue = @fieldParentPtr("value", value);
|
||||||
|
|
||||||
|
try writer.writeAll("[ ");
|
||||||
|
|
||||||
|
var first = true;
|
||||||
|
for (self.array) |val| {
|
||||||
|
if (!first) {
|
||||||
|
try writer.writeAll(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
try val.print(writer, format, indent_level);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try writer.writeAll(" ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toString(value: *const JSONValue, allocator: std.mem.Allocator, format: JSONFormat, indent_level: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
const self: *const JSONArrayValue = @fieldParentPtr("value", value);
|
||||||
|
var str = std.ArrayList(u8).init(allocator);
|
||||||
|
|
||||||
|
try str.appendSlice("[ ");
|
||||||
|
|
||||||
|
var first = true;
|
||||||
|
for (self.array) |val| {
|
||||||
|
if (!first) {
|
||||||
|
try str.appendSlice(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
const valstr = try val.toString(allocator, format, indent_level);
|
||||||
|
defer allocator.free(valstr);
|
||||||
|
try str.appendSlice(valstr);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try str.appendSlice(" ]");
|
||||||
|
|
||||||
|
return str.toOwnedSlice();
|
||||||
|
}
|
||||||
|
|
||||||
fn deinit(value: *JSONValue) void {
|
fn deinit(value: *JSONValue) void {
|
||||||
var self: *JSONArrayValue = @fieldParentPtr("value", value);
|
var self: *JSONArrayValue = @fieldParentPtr("value", value);
|
||||||
for (self.array) |val| {
|
for (self.array) |val| {
|
||||||
@ -146,16 +287,16 @@ const JSONArrayValue = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSONObjectValue = struct {
|
pub const JSONObjectValue = struct {
|
||||||
value: JSONValue,
|
value: JSONValue,
|
||||||
object: *JSONObject,
|
object: *JSONObject,
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator, object: *JSONObject) !*JSONValue {
|
pub fn create(allocator: std.mem.Allocator, object: *JSONObject) !*JSONValue {
|
||||||
var self = try allocator.create(JSONObjectValue);
|
var self = try allocator.create(JSONObjectValue);
|
||||||
self.object = object;
|
self.object = object;
|
||||||
self.value = .{
|
self.value = .{
|
||||||
.type = .Object,
|
.type = .Object,
|
||||||
.vtable = .{ .getObject = getValue, .deinit = deinit },
|
.vtable = .{ .getObject = getValue, .print = print, .toString = toString, .deinit = deinit },
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -167,6 +308,16 @@ const JSONObjectValue = struct {
|
|||||||
return self.object;
|
return self.object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print(value: *const JSONValue, writer: std.fs.File.Writer, format: JSONFormat, indent_level: usize) std.fs.File.WriteError!void {
|
||||||
|
const self: *const JSONObjectValue = @fieldParentPtr("value", value);
|
||||||
|
try self.object.print(writer, format, indent_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toString(value: *const JSONValue, allocator: std.mem.Allocator, format: JSONFormat, indent_level: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
const self: *const JSONObjectValue = @fieldParentPtr("value", value);
|
||||||
|
return self.object.toString(allocator, format, indent_level);
|
||||||
|
}
|
||||||
|
|
||||||
fn deinit(value: *JSONValue) void {
|
fn deinit(value: *JSONValue) void {
|
||||||
var self: *const JSONObjectValue = @fieldParentPtr("value", value);
|
var self: *const JSONObjectValue = @fieldParentPtr("value", value);
|
||||||
self.object.deinit();
|
self.object.deinit();
|
||||||
@ -174,16 +325,16 @@ const JSONObjectValue = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSONIntValue = struct {
|
pub const JSONIntValue = struct {
|
||||||
value: JSONValue,
|
value: JSONValue,
|
||||||
int: isize,
|
int: isize,
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator, value: isize) !*JSONValue {
|
pub fn create(allocator: std.mem.Allocator, value: isize) !*JSONValue {
|
||||||
var self = try allocator.create(JSONIntValue);
|
var self = try allocator.create(JSONIntValue);
|
||||||
self.int = value;
|
self.int = value;
|
||||||
self.value = .{
|
self.value = .{
|
||||||
.type = .Int,
|
.type = .Int,
|
||||||
.vtable = .{ .getInt = getValue, .deinit = deinit },
|
.vtable = .{ .getInt = getValue, .print = print, .toString = toString, .deinit = deinit },
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,22 +346,32 @@ const JSONIntValue = struct {
|
|||||||
return self.int;
|
return self.int;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print(value: *const JSONValue, writer: std.fs.File.Writer, _: JSONFormat, _: usize) std.fs.File.WriteError!void {
|
||||||
|
const self: *const JSONIntValue = @fieldParentPtr("value", value);
|
||||||
|
try writer.print("{d}", .{self.int});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toString(value: *const JSONValue, allocator: std.mem.Allocator, _: JSONFormat, _: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
const self: *const JSONIntValue = @fieldParentPtr("value", value);
|
||||||
|
return std.fmt.allocPrint(allocator, "{d}", .{self.int});
|
||||||
|
}
|
||||||
|
|
||||||
fn deinit(value: *JSONValue) void {
|
fn deinit(value: *JSONValue) void {
|
||||||
var self: *JSONIntValue = @fieldParentPtr("value", value);
|
var self: *JSONIntValue = @fieldParentPtr("value", value);
|
||||||
self.value.allocator.destroy(self);
|
self.value.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSONFloatValue = struct {
|
pub const JSONFloatValue = struct {
|
||||||
value: JSONValue,
|
value: JSONValue,
|
||||||
float: f64,
|
float: f64,
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator, value: f64) !*JSONValue {
|
pub fn create(allocator: std.mem.Allocator, value: f64) !*JSONValue {
|
||||||
var self = try allocator.create(JSONFloatValue);
|
var self = try allocator.create(JSONFloatValue);
|
||||||
self.float = value;
|
self.float = value;
|
||||||
self.value = .{
|
self.value = .{
|
||||||
.type = .Float,
|
.type = .Float,
|
||||||
.vtable = .{ .getFloat = getValue, .deinit = deinit },
|
.vtable = .{ .getFloat = getValue, .print = print, .toString = toString, .deinit = deinit },
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -222,22 +383,32 @@ const JSONFloatValue = struct {
|
|||||||
return self.float;
|
return self.float;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print(value: *const JSONValue, writer: std.fs.File.Writer, _: JSONFormat, _: usize) std.fs.File.WriteError!void {
|
||||||
|
const self: *const JSONFloatValue = @fieldParentPtr("value", value);
|
||||||
|
try writer.print("{d}", .{self.float});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toString(value: *const JSONValue, allocator: std.mem.Allocator, _: JSONFormat, _: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
const self: *const JSONFloatValue = @fieldParentPtr("value", value);
|
||||||
|
return std.fmt.allocPrint(allocator, "{d}", .{self.float});
|
||||||
|
}
|
||||||
|
|
||||||
fn deinit(value: *JSONValue) void {
|
fn deinit(value: *JSONValue) void {
|
||||||
var self: *JSONIntValue = @fieldParentPtr("value", value);
|
var self: *const JSONFloatValue = @fieldParentPtr("value", value);
|
||||||
self.value.allocator.destroy(self);
|
self.value.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSONBoolValue = struct {
|
pub const JSONBoolValue = struct {
|
||||||
value: JSONValue,
|
value: JSONValue,
|
||||||
boolean: bool,
|
boolean: bool,
|
||||||
|
|
||||||
fn init(allocator: std.mem.Allocator, value: bool) !*JSONValue {
|
pub fn create(allocator: std.mem.Allocator, value: bool) !*JSONValue {
|
||||||
var self = try allocator.create(JSONBoolValue);
|
var self = try allocator.create(JSONBoolValue);
|
||||||
self.boolean = value;
|
self.boolean = value;
|
||||||
self.value = .{
|
self.value = .{
|
||||||
.type = .Bool,
|
.type = .Bool,
|
||||||
.vtable = .{ .getBool = getValue, .deinit = deinit },
|
.vtable = .{ .getBool = getValue, .print = print, .toString = toString, .deinit = deinit },
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -249,6 +420,24 @@ const JSONBoolValue = struct {
|
|||||||
return self.boolean;
|
return self.boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print(value: *const JSONValue, writer: std.fs.File.Writer, _: JSONFormat, _: usize) std.fs.File.WriteError!void {
|
||||||
|
const self: *const JSONBoolValue = @fieldParentPtr("value", value);
|
||||||
|
if (self.boolean) {
|
||||||
|
try writer.writeAll("true");
|
||||||
|
} else {
|
||||||
|
try writer.writeAll("false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toString(value: *const JSONValue, allocator: std.mem.Allocator, _: JSONFormat, _: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
const self: *const JSONBoolValue = @fieldParentPtr("value", value);
|
||||||
|
if (self.boolean) {
|
||||||
|
return try allocator.dupe(u8, "true");
|
||||||
|
} else {
|
||||||
|
return try allocator.dupe(u8, "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn deinit(value: *JSONValue) void {
|
fn deinit(value: *JSONValue) void {
|
||||||
var self: *JSONBoolValue = @fieldParentPtr("value", value);
|
var self: *JSONBoolValue = @fieldParentPtr("value", value);
|
||||||
self.value.allocator.destroy(self);
|
self.value.allocator.destroy(self);
|
||||||
@ -259,12 +448,12 @@ pub const JSONStringValue = struct {
|
|||||||
value: JSONValue,
|
value: JSONValue,
|
||||||
string: []const u8,
|
string: []const u8,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, string: []const u8) !*JSONValue {
|
pub fn create(allocator: std.mem.Allocator, string: []const u8) !*JSONValue {
|
||||||
var self = try allocator.create(JSONStringValue);
|
var self = try allocator.create(JSONStringValue);
|
||||||
self.string = string;
|
self.string = string;
|
||||||
self.value = .{
|
self.value = .{
|
||||||
.type = .String,
|
.type = .String,
|
||||||
.vtable = .{ .getString = getValue, .deinit = deinit },
|
.vtable = .{ .getString = getValue, .print = print, .toString = toString, .deinit = deinit },
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -276,6 +465,16 @@ pub const JSONStringValue = struct {
|
|||||||
return self.string;
|
return self.string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print(value: *const JSONValue, writer: std.fs.File.Writer, _: JSONFormat, _: usize) std.fs.File.WriteError!void {
|
||||||
|
const self: *const JSONStringValue = @fieldParentPtr("value", value);
|
||||||
|
try writer.print("\"{s}\"", .{self.string});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toString(value: *const JSONValue, allocator: std.mem.Allocator, _: JSONFormat, _: usize) std.mem.Allocator.Error![]const u8 {
|
||||||
|
const self: *const JSONStringValue = @fieldParentPtr("value", value);
|
||||||
|
return std.fmt.allocPrint(allocator, "\"{s}\"", .{self.string});
|
||||||
|
}
|
||||||
|
|
||||||
fn deinit(value: *JSONValue) void {
|
fn deinit(value: *JSONValue) void {
|
||||||
var self: *JSONStringValue = @fieldParentPtr("value", value);
|
var self: *JSONStringValue = @fieldParentPtr("value", value);
|
||||||
self.value.allocator.free(self.string);
|
self.value.allocator.free(self.string);
|
||||||
@ -300,6 +499,14 @@ pub fn parseString(allocator: std.mem.Allocator, string: []const u8) !*JSONObjec
|
|||||||
return parser.parse();
|
return parser.parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeToFile(fileName: []const u8, json: *JSONObject, format: JSONFormat) !void {
|
||||||
|
var file = try std.fs.cwd().createFile(fileName, .{});
|
||||||
|
defer file.close();
|
||||||
|
const writer = file.writer();
|
||||||
|
|
||||||
|
return json.print(writer, format, 0);
|
||||||
|
}
|
||||||
|
|
||||||
const JSONParser = struct {
|
const JSONParser = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
iter: std.unicode.Utf8Iterator,
|
iter: std.unicode.Utf8Iterator,
|
||||||
@ -354,7 +561,7 @@ const JSONParser = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parseObject(self: *JSONParser) JSONError!*JSONObject {
|
fn parseObject(self: *JSONParser) JSONError!*JSONObject {
|
||||||
const obj = try JSONObject.init(self.allocator);
|
const obj = try JSONObject.create(self.allocator);
|
||||||
errdefer obj.deinit();
|
errdefer obj.deinit();
|
||||||
|
|
||||||
try self.expectNext('{');
|
try self.expectNext('{');
|
||||||
@ -427,7 +634,7 @@ const JSONParser = struct {
|
|||||||
'"' => {
|
'"' => {
|
||||||
//std.debug.print("Parsing string\n", .{});
|
//std.debug.print("Parsing string\n", .{});
|
||||||
const str = try self.parseString();
|
const str = try self.parseString();
|
||||||
value = try JSONStringValue.init(self.allocator, str);
|
value = try JSONStringValue.create(self.allocator, str);
|
||||||
},
|
},
|
||||||
'-', '0'...'9' => {
|
'-', '0'...'9' => {
|
||||||
//std.debug.print("Parsing number\n", .{});
|
//std.debug.print("Parsing number\n", .{});
|
||||||
@ -436,17 +643,17 @@ const JSONParser = struct {
|
|||||||
'{' => {
|
'{' => {
|
||||||
//std.debug.print("Parsing object\n", .{});
|
//std.debug.print("Parsing object\n", .{});
|
||||||
const obj = try self.parseObject();
|
const obj = try self.parseObject();
|
||||||
value = try JSONObjectValue.init(self.allocator, obj);
|
value = try JSONObjectValue.create(self.allocator, obj);
|
||||||
},
|
},
|
||||||
'[' => {
|
'[' => {
|
||||||
//std.debug.print("Parsing array\n", .{});
|
//std.debug.print("Parsing array\n", .{});
|
||||||
const arr = try self.parseArray();
|
const arr = try self.parseArray();
|
||||||
value = try JSONArrayValue.init(self.allocator, arr);
|
value = try JSONArrayValue.create(self.allocator, arr);
|
||||||
},
|
},
|
||||||
't', 'f' => {
|
't', 'f' => {
|
||||||
//std.debug.print("Parsing bool\n", .{});
|
//std.debug.print("Parsing bool\n", .{});
|
||||||
const b = try self.parseBool();
|
const b = try self.parseBool();
|
||||||
value = try JSONBoolValue.init(self.allocator, b);
|
value = try JSONBoolValue.create(self.allocator, b);
|
||||||
},
|
},
|
||||||
'n' => {
|
'n' => {
|
||||||
//std.debug.print("Parsing null\n", .{});
|
//std.debug.print("Parsing null\n", .{});
|
||||||
@ -640,10 +847,10 @@ const JSONParser = struct {
|
|||||||
value *= std.math.pow(f64, 10.0, @floatFromInt(exp));
|
value *= std.math.pow(f64, 10.0, @floatFromInt(exp));
|
||||||
}
|
}
|
||||||
|
|
||||||
return try JSONFloatValue.init(self.allocator, value);
|
return try JSONFloatValue.create(self.allocator, value);
|
||||||
} else {
|
} else {
|
||||||
const value: isize = std.fmt.parseInt(isize, buf.items, 10) catch unreachable;
|
const value: isize = std.fmt.parseInt(isize, buf.items, 10) catch unreachable;
|
||||||
return try JSONIntValue.init(self.allocator, value);
|
return try JSONIntValue.create(self.allocator, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -892,3 +1099,8 @@ test "file parsing" {
|
|||||||
const root = try parseFile(std.testing.allocator, "test/test.json");
|
const root = try parseFile(std.testing.allocator, "test/test.json");
|
||||||
root.deinit();
|
root.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "123" {
|
||||||
|
var root = try JSONObject.create(std.testing.allocator);
|
||||||
|
defer root.deinit();
|
||||||
|
}
|
||||||
|
14
src/main.zig
14
src/main.zig
@ -8,12 +8,14 @@ pub fn main() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const allocator = gpa.allocator();
|
|
||||||
defer {
|
defer {
|
||||||
if (gpa.deinit() == .leak) {
|
if (gpa.deinit() == .leak) {
|
||||||
std.debug.print("Memory was leaked D:\n", .{});
|
std.debug.print("Memory was leaked D:\n", .{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var arena = std.heap.ArenaAllocator.init(gpa.allocator());
|
||||||
|
defer arena.deinit();
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
const fileName = std.mem.span(std.os.argv[1]);
|
const fileName = std.mem.span(std.os.argv[1]);
|
||||||
|
|
||||||
@ -21,10 +23,18 @@ pub fn main() void {
|
|||||||
std.debug.print("Failed to parse json: {any}\n", .{err});
|
std.debug.print("Failed to parse json: {any}\n", .{err});
|
||||||
std.process.exit(2);
|
std.process.exit(2);
|
||||||
};
|
};
|
||||||
defer root.deinit();
|
//defer root.deinit();
|
||||||
|
|
||||||
printObject(root, 0);
|
printObject(root, 0);
|
||||||
std.debug.print("\n", .{});
|
std.debug.print("\n", .{});
|
||||||
|
|
||||||
|
const stdout = std.io.getStdOut();
|
||||||
|
const writer = stdout.writer();
|
||||||
|
root.print(writer, .{}, 0) catch {};
|
||||||
|
std.debug.print("\n", .{});
|
||||||
|
|
||||||
|
const json_str = root.toString(allocator, .{}, 0) catch return;
|
||||||
|
std.debug.print("{s}\n", .{json_str});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printIndent(indent: usize) void {
|
fn printIndent(indent: usize) void {
|
||||||
|
Loading…
Reference in New Issue
Block a user