Pretty, a pretty printer for deeply nested data structures in Zig

I’m excited* to publish my first Zig project – pretty, a simple pretty printer for inspecting complex and deeply-nested data structures.

I developed it as part of my language project to inspect complex trees (AST). Later on, I realized how useful it is on its own. So, I spent a couple of months honing it. With various printing options, you can almost “query” the things you want to see in your data. While it doesn’t yet support every type for laying out things nicely, I believe I covered the most important ones. Feel free to check it out!

Here is the demo (excerpt from the repo):


simplified version of src/demo.zig:

// main.zig
const std = @import("std");
const pretty = @import("pretty.zig");
const alloc = std.heap.page_allocator;

pub fn main() !void {
    const array = [3]u8{ 4, 5, 6 };

    // print with default options
    try pretty.print(alloc, array, .{});

    // customized print
    try pretty.print(alloc, array, .{
        .arr_show_item_idx = false,
        .arr_max_len = 2,
    });

    // don't print, get a string!
    var out = try pretty.dump(alloc, array, .{});
    defer alloc.free(out);
    std.debug.print("{s}..\n", .{out[0..5]});
}

output:

$ zig run main.zig
[3]u8
  0: 4
  1: 5
  2: 6

[3]u8
  4
  5

[3]u8..

*This forum (and Discord server) helped me immensely to get through the hard times of learning Zig. The effort I put into making the utility I use myself reusable for others is my humble way of saying thank you to the community. Plus, I made my first donation today. So, thank you guys a lot!

13 Likes

Updated to 0.8.4. Now it supports tagged unions and comptime slices. Thanks @speed2exe and @jacobly (from Discord) for precious help :blush:.

Demo:

const std = @import("std");
const pretty = @import("pretty.zig");
const alloc = std.heap.page_allocator;

pub fn main() !void {
    const Union = union(enum) {
        option1: bool,
        option2: u8,
        option3: i32,
    };

    try pretty.print(alloc, @typeInfo(Union), .{});
    try pretty.print(alloc, Union{ .option1 = true }, .{});
}

Result:

builtin.Type
  .Union: builtin.Type.Union
    .layout: builtin.Type.ContainerLayout
      .Auto
    .tag_type: ?type
      @typeInfo(tmp.main.Union).Union.tag_type.?
    .fields: []const builtin.Type.UnionField
      0: builtin.Type.UnionField
        .name: [:0]const u8
          "option1"
        .type: type
          bool
        .alignment: comptime_int
          1
      1: builtin.Type.UnionField
        .name: [:0]const u8
          "option2"
        .type: type
          u8
        .alignment: comptime_int
          1
      2: builtin.Type.UnionField
        .name: [:0]const u8
          "option3"
        .type: type
          i32
        .alignment: comptime_int
          4
    .decls: []const builtin.Type.Declaration
      (empty)

tmp.main.Union
  .option1: bool
    true

1 Like

This is awesome! Great work.

2 Likes