| ... | @@ -415,6 +415,12 @@ pub const Document = struct { | ... | @@ -415,6 +415,12 @@ pub const Document = struct { |
| 415 | _ = options; | 415 | _ = options; |
| 416 | return std.fmt.format(writer, "{}", .{this.root}); | 416 | return std.fmt.format(writer, "{}", .{this.root}); |
| 417 | } | 417 | } |
| | 418 | |
| | 419 | pub fn stringify(this: *const Document, writer: anytype, space: Space, indent: u8) @TypeOf(writer).Error!void { |
| | 420 | const fill = space.fill(); |
| | 421 | for (0..indent) |_| try writer.writeAll(fill); |
| | 422 | return @errorCast(this.root.stringify(writer, space, indent)); |
| | 423 | } |
| 418 | }; | 424 | }; |
| 419 | | 425 | |
| 420 | pub const ValueIndex = enum(u32) { | 426 | pub const ValueIndex = enum(u32) { |
| ... | @@ -433,6 +439,10 @@ pub const ValueIndex = enum(u32) { | ... | @@ -433,6 +439,10 @@ pub const ValueIndex = enum(u32) { |
| 433 | return std.fmt.format(writer, "{}", .{this.v()}); | 439 | return std.fmt.format(writer, "{}", .{this.v()}); |
| 434 | } | 440 | } |
| 435 | | 441 | |
| | 442 | fn stringify(this: ValueIndex, writer: anytype, space: Space, indent: u8) !void { |
| | 443 | return this.v().stringify(writer, space, indent); |
| | 444 | } |
| | 445 | |
| 436 | pub fn v(this: ValueIndex) Value { | 446 | pub fn v(this: ValueIndex) Value { |
| 437 | std.debug.assert(this != .zero); | 447 | std.debug.assert(this != .zero); |
| 438 | std.debug.assert(doc != null); // make sure to call Document.acquire() | 448 | std.debug.assert(doc != null); // make sure to call Document.acquire() |
| ... | @@ -493,6 +503,17 @@ pub const Value = union(enum(u8)) { | ... | @@ -493,6 +503,17 @@ pub const Value = union(enum(u8)) { |
| 493 | inline .object, .array, .string, .number => |t| std.fmt.format(writer, "{}", .{t}), | 503 | inline .object, .array, .string, .number => |t| std.fmt.format(writer, "{}", .{t}), |
| 494 | }; | 504 | }; |
| 495 | } | 505 | } |
| | 506 | |
| | 507 | fn stringify(this: Value, writer: anytype, space: Space, indent: u8) anyerror!void { |
| | 508 | return switch (this) { |
| | 509 | .zero => unreachable, |
| | 510 | .null => writer.writeAll("null"), |
| | 511 | .true => writer.writeAll("true"), |
| | 512 | .false => writer.writeAll("false"), |
| | 513 | inline .object, .array => |t| t.stringify(writer, space, indent), |
| | 514 | inline .string, .number => |t| t.stringify(writer), |
| | 515 | }; |
| | 516 | } |
| 496 | }; | 517 | }; |
| 497 | | 518 | |
| 498 | pub const Array = []align(1) const ValueIndex; | 519 | pub const Array = []align(1) const ValueIndex; |
| ... | @@ -508,6 +529,12 @@ pub const StringIndex = enum(u32) { | ... | @@ -508,6 +529,12 @@ pub const StringIndex = enum(u32) { |
| 508 | try writer.writeAll("\""); | 529 | try writer.writeAll("\""); |
| 509 | } | 530 | } |
| 510 | | 531 | |
| | 532 | fn stringify(this: StringIndex, writer: anytype) anyerror!void { |
| | 533 | try writer.writeAll("\""); |
| | 534 | try writer.writeAll(this.to()); |
| | 535 | try writer.writeAll("\""); |
| | 536 | } |
| | 537 | |
| 511 | pub fn to(this: StringIndex) []const u8 { | 538 | pub fn to(this: StringIndex) []const u8 { |
| 512 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; | 539 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; |
| 513 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .string); | 540 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .string); |
| ... | @@ -532,6 +559,21 @@ pub const ArrayIndex = enum(u32) { | ... | @@ -532,6 +559,21 @@ pub const ArrayIndex = enum(u32) { |
| 532 | try writer.writeAll("]"); | 559 | try writer.writeAll("]"); |
| 533 | } | 560 | } |
| 534 | | 561 | |
| | 562 | fn stringify(this: ArrayIndex, writer: anytype, space: Space, indent: u8) anyerror!void { |
| | 563 | const fill = space.fill(); |
| | 564 | const items = this.to(); |
| | 565 | try writer.writeAll("["); |
| | 566 | for (items, 0..) |item, i| { |
| | 567 | if (i > 0) try writer.writeAll(","); |
| | 568 | if (fill.len > 0) try writer.writeAll("\n"); |
| | 569 | for (0..indent + 1) |_| try writer.writeAll(fill); |
| | 570 | try item.stringify(writer, space, indent + 1); |
| | 571 | } |
| | 572 | if (fill.len > 0) try writer.writeAll("\n"); |
| | 573 | for (0..indent) |_| try writer.writeAll(fill); |
| | 574 | try writer.writeAll("]"); |
| | 575 | } |
| | 576 | |
| 535 | pub fn to(this: ArrayIndex) Array { | 577 | pub fn to(this: ArrayIndex) Array { |
| 536 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; | 578 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; |
| 537 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .array); | 579 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .array); |
| ... | @@ -558,6 +600,23 @@ pub const ObjectIndex = enum(u32) { | ... | @@ -558,6 +600,23 @@ pub const ObjectIndex = enum(u32) { |
| 558 | try writer.writeAll("}"); | 600 | try writer.writeAll("}"); |
| 559 | } | 601 | } |
| 560 | | 602 | |
| | 603 | fn stringify(this: ObjectIndex, writer: anytype, space: Space, indent: u8) anyerror!void { |
| | 604 | const fill = space.fill(); |
| | 605 | const keys, const values = this.to(); |
| | 606 | try writer.writeAll("{"); |
| | 607 | for (keys, values, 0..) |k, v, i| { |
| | 608 | if (i > 0) try writer.writeAll(","); |
| | 609 | if (fill.len > 0) try writer.writeAll("\n"); |
| | 610 | for (0..indent + 1) |_| try writer.writeAll(fill); |
| | 611 | try k.stringify(writer); |
| | 612 | try writer.writeAll(":"); |
| | 613 | try v.stringify(writer, space, indent + 1); |
| | 614 | } |
| | 615 | if (fill.len > 0) try writer.writeAll("\n"); |
| | 616 | for (0..indent) |_| try writer.writeAll(fill); |
| | 617 | try writer.writeAll("}"); |
| | 618 | } |
| | 619 | |
| 561 | pub fn to(this: ObjectIndex) struct { []align(1) const StringIndex, Array } { | 620 | pub fn to(this: ObjectIndex) struct { []align(1) const StringIndex, Array } { |
| 562 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; | 621 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; |
| 563 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .object); | 622 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .object); |
| ... | @@ -614,6 +673,10 @@ pub const NumberIndex = enum(u32) { | ... | @@ -614,6 +673,10 @@ pub const NumberIndex = enum(u32) { |
| 614 | try writer.writeAll(this.to()); | 673 | try writer.writeAll(this.to()); |
| 615 | } | 674 | } |
| 616 | | 675 | |
| | 676 | fn stringify(this: NumberIndex, writer: anytype) anyerror!void { |
| | 677 | try writer.writeAll(this.to()); |
| | 678 | } |
| | 679 | |
| 617 | pub fn to(this: NumberIndex) []const u8 { | 680 | pub fn to(this: NumberIndex) []const u8 { |
| 618 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; | 681 | var d = doc.?.extras.ptr[@intFromEnum(this)..]; |
| 619 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .number); | 682 | std.debug.assert(@as(Value.Tag, @enumFromInt(d[0])) == .number); |
| ... | @@ -629,3 +692,15 @@ pub const NumberIndex = enum(u32) { | ... | @@ -629,3 +692,15 @@ pub const NumberIndex = enum(u32) { |
| 629 | }; | 692 | }; |
| 630 | } | 693 | } |
| 631 | }; | 694 | }; |
| | 695 | |
| | 696 | const Space = union(enum) { |
| | 697 | count: u8, |
| | 698 | custom: []const u8, |
| | 699 | |
| | 700 | pub fn fill(s: Space) []const u8 { |
| | 701 | return switch (s) { |
| | 702 | .count => |c| " "[0..@min(c, 10)], |
| | 703 | .custom => |f| f[0..@min(f.len, 10)], |
| | 704 | }; |
| | 705 | } |
| | 706 | }; |