{"id":15476124,"url":"https://github.com/speed2exe/tree-fmt","last_synced_at":"2025-04-15T16:19:02.431Z","repository":{"id":65532669,"uuid":"592270274","full_name":"speed2exe/tree-fmt","owner":"speed2exe","description":"Tree-like pretty formatter for Zig","archived":false,"fork":false,"pushed_at":"2025-03-06T14:14:02.000Z","size":1287,"stargazers_count":40,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-15T16:18:56.508Z","etag":null,"topics":["zig-library","zig-package"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/speed2exe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-23T11:11:42.000Z","updated_at":"2025-03-22T22:40:55.000Z","dependencies_parsed_at":"2023-11-27T18:28:47.995Z","dependency_job_id":"2c72c234-cce4-4f55-89d6-d92d175447cd","html_url":"https://github.com/speed2exe/tree-fmt","commit_stats":{"total_commits":59,"total_committers":2,"mean_commits":29.5,"dds":0.0847457627118644,"last_synced_commit":"83821aaccd8c0d39ba45e0eadb95efc7d6bb7738"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speed2exe%2Ftree-fmt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speed2exe%2Ftree-fmt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speed2exe%2Ftree-fmt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/speed2exe%2Ftree-fmt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/speed2exe","download_url":"https://codeload.github.com/speed2exe/tree-fmt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249105475,"owners_count":21213537,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["zig-library","zig-package"],"created_at":"2024-10-02T03:22:56.203Z","updated_at":"2025-04-15T16:19:02.411Z","avatar_url":"https://github.com/speed2exe.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tree Formattar for Zig\n- Pretty prints out Zig Values for your debugging needs.\n- If you faces any issue with formatting, kindly open an issue.\n\n## Versioning\n- Current `main` branch tracks zig latest version\n- If you need a stable version, see release tags\n\n## Objective\n- Provide a colored tree-like visual representation of a Zig value to aid in debugging.\n\n## Features\n- Colored output to distinguish between types and values\n- Indentation to show the structure of the value\n- Special formatters for following types (Do file a PR or FR if you think there are more types that can require special formatting)\n  - `std.MultiArrayList`\n  - `std.HashMapUnmanaged`\n\n## Screenshot\n![Screenshot](./images/screenshot.png)\n\n## Example\n- You can run on of the examples in the `examples` by executing the following command:\n```bash\nzig build test -Dtest-filter=\"anon struct 1\"\n```\n- You might need to require to remove `zig-cache` to run it again without changes.\n\n## Usage\n- Zig Package Manager Example: https://github.com/speed2exe/tree-fmt-example\n- `zig.build.zon`\n```zon\n.{\n    .name = \"your_package_name\",\n    .version = \"0.0.1\",\n    .dependencies = .{\n        .tree_fmt = .{\n            // c6398b225f15cdbe35b3951920f634ffd1c65c12 is just commit hash\n            .url = \"https://github.com/speed2exe/tree-fmt/archive/c6398b225f15cdbe35b3951920f634ffd1c65c12.tar.gz\",\n            // just do `zig build`, get the error code and replace with expected hash\n            .hash = \"12201dceb9a9c2c9a6fc83105a7f408132b9ab69173b266e7df2af2c1dd6f814cd51\",\n        },\n    },\n    .paths = .{ \"\" },\n}\n```\n- `build.zig`\n```zig\npub fn build(b: *std.Build) void {\n    // ...\n    const dep = b.dependency(\"tree_fmt\", .{});\n    const tree_fmt = dep.module(\"tree-fmt\");\n    your_program.root_module.addImport(\"tree-fmt\", tree_fmt);\n}\n```\n\n### Quick Setup\n- Fastest and easiest way to if you want to save time and effort.\n- This example is in `example_default_tree_formatter.zig`\n\n```zig\nvar tree_formatter = @import(\"tree-fmt\").defaultFormatter();\n\npub fn main() !void {\n    const my_struct = .{ 1, 2.4, \"hi\" };\n    try tree_formatter.format(my_struct, .{\n        .name = \"my_struct\", // (optional) just an identifier to the root of the tree\n    });\n}\n```\n- Output:\n```\nsome_anon_struct: tuple{comptime comptime_int = 1, comptime comptime_float = 2.4, comptime *const [2:0]u8 = \"hi\"}\n├─.0: comptime_int =\u003e 1\n├─.1: comptime_float =\u003e 2.4e+00\n└─.2: *const [2:0]u8 @21d169\n  └─.*: [2:0]u8 hi\n    ├─[0]: u8 =\u003e 104\n    └─[1]: u8 =\u003e 105\n```\n\n\n### Proper Setup\n- This is recommended, as it gives you more control over writer, allocator and settings.\n\n```zig\nconst std = @import(\"std\");\n\n// add imports here\nconst treeFormatter = @import(\"tree-fmt\").treeFormatter;\n\npub fn main() !void {\n    // initialize your allocator\n    var gpa = std.heap.GeneralPurposeAllocator(.{}){};\n    const allocator = gpa.allocator();\n    defer {\n        const leaked = gpa.deinit();\n        if (leaked) {\n            @panic(\"leaked memory!\");\n        }\n    }\n\n    // initialize a writer (std.io.Writer)\n    // tips if you print a lot: wrap with std.io.BufferedWriter to improve performance\n    var w = std.io.getStdOut().writer();\n\n    // initialize TreeFormatter with allocator and writer\n    var tree_formatter = treeFormatter(allocator, w);\n\n    // initialize your value\n    var sentinel_array: [*:0]const u8 = \"hello world\";\n\n    // call the method with writer and value\n    try tree_formatter.formatValueWithId(sentinel_array, .{\n        // .name = \"sentinel_array\", \u003c-- example setting\n        // you can find settings at @import(\"./src/tree_fmt.zig\").TreeFormatterSettings;\n        // you can also leave it blank to use default settings\n    });\n}\n```\n\n- Output:\n```\nsentinel_array: [*:0]const u8 @20a71e \"hello world\"\n├─[0]: u8 =\u003e 104\n├─[1]: u8 =\u003e 101\n├─[2]: u8 =\u003e 108\n├─[3]: u8 =\u003e 108\n├─[4]: u8 =\u003e 111\n├─[5]: u8 =\u003e 32\n├─[6]: u8 =\u003e 119\n├─[7]: u8 =\u003e 111\n├─[8]: u8 =\u003e 114\n├─[9]: u8 =\u003e 108\n└─... (showed first 10 out of 11 items only)\n```\n\n- You can find other examples in the `examples` directory. To run specific example(s):\n```bash\n    zig build test -Dtest-filter=\"name of test\"\n    # e.g. zig build test -Dtest-filter=\"anon struct 1\"\n```\n\n## Example\n- `std.ArrayList(u8)`\n```\n.: array_list.ArrayListAligned(u8,null)\n├─.items: []u8 @7efcc912f000\n│ ├─[0]: u8 =\u003e 0\n│ ├─[1]: u8 =\u003e 1\n│ ├─[2]: u8 =\u003e 2\n│ ├─[3]: u8 =\u003e 3\n│ ├─[4]: u8 =\u003e 4\n│ └─... (showed first 5 out of 100 items only)\n├─.capacity: usize =\u003e 105\n└─.allocator: mem.Allocator\n  ├─.ptr: *anyopaque @7fffadc5b3d8\n  └─.vtable: *const mem.Allocator.VTable @202a38\n    └─.*: mem.Allocator.VTable\n      ├─.alloc: *const fn(*anyopaque, usize, u8, usize) ?[*]u8 @238e00\n      ├─.resize: *const fn(*anyopaque, []u8, u8, usize, usize) bool @2393c0\n      └─.free: *const fn(*anyopaque, []u8, u8, usize) void @23a2d0\n```\n\n- `std.AutoHashMap(u8, u8)`\n```\nmap: hash_map.HashMap(u8,u8,hash_map.AutoContext(u8),80)\n├─.unmanaged: hash_map.HashMapUnmanaged(u8,u8,hash_map.AutoContext(u8),80)\n│ ├─.iterator()\n│ │ ├─.next(): hash_map.HashMapUnmanaged(u8,u8,hash_map.AutoContext(u8),80).Entry\n│ │ │ ├─.key_ptr: *u8 @7fcad47f5021\n│ │ │ │ └─.*: u8 =\u003e 1\n│ │ │ └─.value_ptr: *u8 @7fcad47f5029\n│ │ │   └─.*: u8 =\u003e 2\n│ │ ├─.next(): hash_map.HashMapUnmanaged(u8,u8,hash_map.AutoContext(u8),80).Entry\n│ │ │ ├─.key_ptr: *u8 @7fcad47f5022\n│ │ │ │ └─.*: u8 =\u003e 0\n│ │ │ └─.value_ptr: *u8 @7fcad47f502a\n│ │ │   └─.*: u8 =\u003e 0\n│ │ └─.next(): hash_map.HashMapUnmanaged(u8,u8,hash_map.AutoContext(u8),80).Entry\n│ │   ├─.key_ptr: *u8 @7fcad47f5026\n│ │   │ └─.*: u8 =\u003e 2\n│ │   └─.value_ptr: *u8 @7fcad47f502e\n│ │     └─.*: u8 =\u003e 4\n│ ├─.metadata: ?[*]hash_map.HashMapUnmanaged(u8,u8,hash_map.AutoContext(u8),80).Metadata\n│ │ └─.?: [*]hash_map.HashMapUnmanaged(u8,u8,hash_map.AutoContext(u8),80).Metadata @7fcad47f5018\n│ ├─.size: u32 =\u003e 3\n│ └─.available: u32 =\u003e 3\n├─.allocator: mem.Allocator\n│ ├─.ptr: *anyopaque @7ffc3b6baca0\n│ └─.vtable: *const mem.Allocator.VTable @2045b8\n│   └─.*: mem.Allocator.VTable\n│     ├─.alloc: *const fn(*anyopaque, usize, u8, usize) ?[*]u8 @2433a0\n│     ├─.resize: *const fn(*anyopaque, []u8, u8, usize, usize) bool @243960\n│     └─.free: *const fn(*anyopaque, []u8, u8, usize) void @244870\n└─.ctx: hash_map.AutoContext(u8) =\u003e .{}\n```\n\n- `std.MultiArrayList...` (see `example_multi_array_list.zig`)\n```\nmulti_array_list: multi_array_list.MultiArrayList(example_multi_array_list.Person)\n├─.slice(): multi_array_list.MultiArrayList(example_multi_array_list.Person).Slice\n│ └─.items\n│   ├─(.id): []u64 @7f8cf20c3000\n│   │ ├─[0]: u64 =\u003e 0\n│   │ ├─[1]: u64 =\u003e 1\n│   │ ├─[2]: u64 =\u003e 2\n│   │ ├─[3]: u64 =\u003e 3\n│   │ ├─[4]: u64 =\u003e 4\n│   │ └─... (showed first 5 out of 7 items only)\n│   ├─(.age): []u8 @7f8cf20c3080\n│   │ ├─[0]: u8 =\u003e 0\n│   │ ├─[1]: u8 =\u003e 1\n│   │ ├─[2]: u8 =\u003e 2\n│   │ ├─[3]: u8 =\u003e 3\n│   │ ├─[4]: u8 =\u003e 4\n│   │ └─... (showed first 5 out of 7 items only)\n│   └─(.car): []example_multi_array_list.Car @7f8cf20c3040\n│     ├─[0]: example_multi_array_list.Car\n│     │ └─.license_plate_no: u64 =\u003e 555\n│     ├─[1]: example_multi_array_list.Car\n│     │ └─.license_plate_no: u64 =\u003e 555\n│     ├─[2]: example_multi_array_list.Car\n│     │ └─.license_plate_no: u64 =\u003e 555\n│     ├─[3]: example_multi_array_list.Car\n│     │ └─.license_plate_no: u64 =\u003e 555\n│     ├─[4]: example_multi_array_list.Car\n│     │ └─.license_plate_no: u64 =\u003e 555\n│     └─... (showed first 5 out of 7 items only)\n├─.get\n│ ├─(0): example_multi_array_list.Person\n│ │ ├─.id: u64 =\u003e 0\n│ │ ├─.age: u8 =\u003e 0\n│ │ └─.car: example_multi_array_list.Car\n│ │   └─.license_plate_no: u64 =\u003e 555\n│ ├─(1): example_multi_array_list.Person\n│ │ ├─.id: u64 =\u003e 1\n│ │ ├─.age: u8 =\u003e 1\n│ │ └─.car: example_multi_array_list.Car\n│ │   └─.license_plate_no: u64 =\u003e 555\n│ ├─(2): example_multi_array_list.Person\n│ │ ├─.id: u64 =\u003e 2\n│ │ ├─.age: u8 =\u003e 2\n│ │ └─.car: example_multi_array_list.Car\n│ │   └─.license_plate_no: u64 =\u003e 555\n│ ├─(3): example_multi_array_list.Person\n│ │ ├─.id: u64 =\u003e 3\n│ │ ├─.age: u8 =\u003e 3\n│ │ └─.car: example_multi_array_list.Car\n│ │   └─.license_plate_no: u64 =\u003e 555\n│ └─... (showed first 4 out of 7 items only)\n├─.bytes: [*]align(8) u8 @7f8cf20c3000\n├─.len: usize =\u003e 7\n└─.capacity: usize =\u003e 8\n```\n\n- `multi_array_list.MultiArrayList(zig.Ast.TokenList__struct_4206).Slice`\n```\nast: multi_array_list.MultiArrayList(zig.Ast.TokenList__struct_4200).Slice\n├─.toMultiArrayList(): multi_array_list.MultiArrayList(zig.Ast.TokenList__struct_4200)\n│ ├─.slice(): multi_array_list.MultiArrayList(zig.Ast.TokenList__struct_4200).Slice\n│ │ └─.items\n│ │   ├─(.tag): []zig.tokenizer.Token.Tag @7ff3c81f7098\n│ │   │ ├─[0]: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.keyword_const (86)\n│ │   │ ├─[1]: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.identifier (2)\n│ │   │ ├─[2]: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.equal (12)\n│ │   │ ├─[3]: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.builtin (7)\n│ │   │ ├─[4]: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.l_paren (16)\n│ │   │ └─... (showed first 5 out of 31 items only)\n│ │   └─(.start): []u32 @7ff3c81f7000\n│ │     ├─[0]: u32 =\u003e 1\n│ │     ├─[1]: u32 =\u003e 7\n│ │     ├─[2]: u32 =\u003e 11\n│ │     ├─[3]: u32 =\u003e 13\n│ │     ├─[4]: u32 =\u003e 20\n│ │     └─... (showed first 5 out of 31 items only)\n│ ├─.get\n│ │ ├─(0): zig.Ast.TokenList__struct_4200\n│ │ │ ├─.tag: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.keyword_const (86)\n│ │ │ └─.start: u32 =\u003e 1\n│ │ ├─(1): zig.Ast.TokenList__struct_4200\n│ │ │ ├─.tag: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.identifier (2)\n│ │ │ └─.start: u32 =\u003e 7\n│ │ ├─(2): zig.Ast.TokenList__struct_4200\n│ │ │ ├─.tag: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.equal (12)\n│ │ │ └─.start: u32 =\u003e 11\n│ │ ├─(3): zig.Ast.TokenList__struct_4200\n│ │ │ ├─.tag: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.builtin (7)\n│ │ │ └─.start: u32 =\u003e 13\n│ │ ├─(4): zig.Ast.TokenList__struct_4200\n│ │ │ ├─.tag: zig.tokenizer.Token.Tag =\u003e zig.tokenizer.Token.Tag.l_paren (16)\n│ │ │ └─.start: u32 =\u003e 20\n│ │ └─... (showed first 5 out of 31 items only)\n│ ├─.bytes: [*]align(4) u8 @7ff3c81f7000\n│ ├─.len: usize =\u003e 31\n│ └─.capacity: usize =\u003e 38\n├─.ptrs: [2][*]u8\n│ ├─[0]: [*]u8 @7ff3c81f7098\n│ └─[1]: [*]u8 @7ff3c81f7000\n├─.len: usize =\u003e 31\n└─.capacity: usize =\u003e 38\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspeed2exe%2Ftree-fmt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspeed2exe%2Ftree-fmt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspeed2exe%2Ftree-fmt/lists"}