A pretty printer for zig
zig
1const std = @import("std");
2const print = std.debug.print;
3
4const build_options = @import("build-options");
5
6const pretty_mod = @import("pretty");
7const pretty = pretty_mod.pretty;
8const prettyO = pretty_mod.prettyO;
9
10pub const pretty_options = pretty_mod.Options{
11 .skip_root_type_name = build_options.skip_root_type_name,
12 .theme = .{
13 .indent_width = build_options.indent_width,
14 },
15};
16
17const employees = @embedFile("employees.json");
18
19const Hello = enum { world, developer };
20
21const Gender = enum(u8) { male, female, nonbinary, other, _ };
22
23const Person = struct {
24 age: u8,
25 gender: ?Gender,
26
27 pub fn pretty(self: *const @This(), comptime ctx: pretty_mod.Context, run: *const pretty_mod.Runtime) !void {
28 run.setColor(ctx, .dim);
29 try run.write("AGE = ");
30 run.resetColor();
31 run.setColorRaw(.bright_magenta);
32 try run.print("{d}", .{self.age});
33 run.resetColor();
34 run.setColor(ctx, .dim);
35 try run.write(", GENDER = ");
36 run.resetColor();
37 run.setColorRaw(.bright_magenta);
38 try run.print("{?}", .{self.gender});
39 run.resetColor();
40 }
41};
42
43const Nested = struct {
44 a: ChildA,
45 b: ChildB,
46};
47
48const ChildA = struct {
49 child: ChildC,
50};
51
52const ChildB = struct {
53 hello: Hello,
54};
55
56const ChildC = struct {
57 person: [2]Person,
58};
59
60const Employee = struct {
61 id: []const u8,
62 name: []const u8,
63 position: []const u8,
64 department: Department,
65 projects: []Project,
66};
67
68const Department = struct {
69 id: []const u8,
70 name: []const u8,
71 manager: Manager,
72
73 const Manager = struct {
74 id: []const u8,
75 name: []const u8,
76 contact: Contact,
77
78 const Contact = struct {
79 email: []const u8,
80 phone: []const u8,
81 };
82 };
83};
84
85const Project = struct {
86 projectId: []const u8,
87 projectName: []const u8,
88 startDate: []const u8,
89 tasks: []Task,
90
91 const Task = struct {
92 taskId: []const u8,
93 title: []const u8,
94 status: []const u8,
95 details: Details,
96
97 const Details = struct {
98 hoursSpent: u32,
99 technologiesUsed: [][]const u8,
100 expectedCompletion: []const u8,
101 };
102 };
103};
104
105const JsonData = union(enum) {
106 employee: Employee,
107};
108
109const ErrorSet = error{ OutOfMemory, WriteFailed };
110const Result = ErrorSet!Hello;
111
112const HelloResult = union(ResultType) {
113 const ResultType = enum { ok, err };
114
115 ok: Hello,
116 err: ErrorSet,
117};
118
119pub fn main(init: std.process.Init) !void {
120 const start = std.Io.Timestamp.now(init.io, .cpu_thread);
121
122 print("Pretty type - {f}\n", .{pretty(Hello)});
123 print("Pretty null - {f}\n", .{pretty(null)});
124
125 print("\nBooleans\n", .{});
126 print("Pretty bool true - {f}\n", .{pretty(true)});
127 print("Pretty bool false - {f}\n", .{pretty(false)});
128 print(
129 "Pretty bool true without type name - {f}\n",
130 .{prettyO(true, .{
131 .skip_root_type_name = true,
132 .theme = .{ .type_value_sep = ": " },
133 })},
134 );
135
136 print("\nUnsigned Integers\n", .{});
137 print("Pretty u8 - {f}\n", .{pretty(@as(u8, 42))});
138 print("Pretty u16 - {f}\n", .{pretty(@as(u16, 42))});
139 print("Pretty u32 - {f}\n", .{pretty(@as(u32, 42))});
140 print("Pretty u64 - {f}\n", .{pretty(@as(u64, 42))});
141 print("Pretty usize - {f}\n", .{pretty(@as(usize, 42))});
142
143 print("\nSigned Integers\n", .{});
144 print("Pretty comptime_int - {f}\n", .{pretty(42)});
145 print("Pretty i8 - {f}\n", .{pretty(@as(i8, 42))});
146 print("Pretty i16 - {f}\n", .{pretty(@as(i16, 42))});
147 print("Pretty i32 - {f}\n", .{pretty(@as(i32, 42))});
148 print("Pretty i64 - {f}\n", .{pretty(@as(i64, 42))});
149 print("Pretty isize - {f}\n", .{pretty(@as(isize, 42))});
150
151 print("\nFloats\n", .{});
152 print("Pretty comptime_float - {f}\n", .{pretty(3.131)});
153 print("Pretty f16 - {f}\n", .{pretty(@as(f16, 3.141))});
154 print("Pretty f32 - {f}\n", .{pretty(@as(f32, 3.141))});
155 print("Pretty f64 - {f}\n", .{pretty(@as(f64, 3.141))});
156
157 print("\nEnums\n", .{});
158 print("Pretty enum - {f}\n", .{pretty(Hello.world)});
159 print("Pretty enum literal - {f}\n", .{pretty(.hello_world)});
160
161 const opt_null: ?Hello = null;
162 const opt_not_null: ?Hello = .developer;
163
164 print("\nOptionals\n", .{});
165 print("Pretty optional = null - {f}\n", .{pretty(opt_null)});
166 print("Pretty optional = not null - {f}\n", .{pretty(opt_not_null)});
167
168 const person = Person{ .age = 13, .gender = null };
169
170 const nested = Nested{
171 .a = .{ .child = .{ .person = .{ person, Person{
172 .age = 42,
173 .gender = .nonbinary,
174 } } } },
175 .b = .{ .hello = .world },
176 };
177
178 print("\nStructs\n", .{});
179 print("Pretty simple struct - {f}\n", .{pretty(person)});
180 print(
181 "Pretty simple inline struct - {f}\n",
182 .{prettyO(person, .{ .struct_inline = true })},
183 );
184 print("Pretty nested struct - {f}\n", .{pretty(nested)});
185
186 const simple_union = HelloResult{ .ok = .world };
187
188 print("\nUnions\n", .{});
189 print("Pretty simple union - {f}\n", .{pretty(simple_union)});
190
191 print("\nArrays\n", .{});
192 print("Pretty array of floats - {f}\n", .{pretty([_]f32{ 0.1, 0.2, 0.3 })});
193 print(
194 "Pretty array of floats inline - {f}\n",
195 .{prettyO([3]f32{ 0.1, 0.2, 0.3 }, .{ .array_inline = true })},
196 );
197 print(
198 "Pretty array of floats inline with indices - {f}\n",
199 .{prettyO([3]f32{ 0.1, 0.2, 0.3 }, .{
200 .array_inline = true,
201 .array_always_show_index = true,
202 })},
203 );
204
205 const zig_logo_color: @Vector(4, u8) = .{ 247, 164, 29, 255 };
206
207 print("\nVectors\n", .{});
208 print("Pretty vector of u8s - {f}\n", .{pretty(zig_logo_color)});
209
210 const ptr_array = [_]f32{ 0.1, 0.3, 0.9 };
211 const persons_allocated = try init.gpa.alloc(Person, 10);
212 defer init.gpa.free(persons_allocated);
213
214 var str_allocated = try init.gpa.alloc(u8, 5);
215 defer init.gpa.free(str_allocated);
216 str_allocated[0] = 'H';
217 str_allocated[1] = 'e';
218 str_allocated[2] = 'l';
219 str_allocated[3] = 'l';
220 str_allocated[4] = 'o';
221
222 var buffer: [100]u8 = [_]u8{1} ** 100;
223 const buffer_ptr: *[100]u8 = &buffer;
224 const buffer_many_ptr: [*]u8 = buffer_ptr;
225
226 print("\nPointers\n", .{});
227 print("Pretty string - {f}\n", .{pretty("Hello World!")});
228 print("Pretty ptr to an array - {f}\n", .{pretty(&ptr_array)});
229 print("Pretty ptr to nested struct - {f}\n", .{pretty(&nested)});
230 print("Pretty ptr to slice of structs - {f}\n", .{pretty(persons_allocated)});
231 print("Pretty ptr to slice of u8 - {f}\n", .{pretty(str_allocated)});
232 print("Pretty ptr to buffer many ptr - {f}\n", .{pretty(buffer_many_ptr)});
233
234 const eu_error: Result = error.OutOfMemory;
235 const eu_ok: Result = .world;
236
237 print("\nError types\n", .{});
238 print("Pretty error set - {f}\n", .{pretty(ErrorSet.OutOfMemory)});
239 print("Pretty error union error - {f}\n", .{pretty(eu_error)});
240 print("Pretty error union ok - {f}\n", .{pretty(eu_ok)});
241
242 print("\nFunctions\n", .{});
243 print("Pretty function pretty - {f}\n", .{pretty(pretty)});
244 print("Pretty function main - {f}\n", .{pretty(main)});
245
246 const parsed: std.json.Parsed(JsonData) = try std.json.parseFromSlice(JsonData, init.gpa, employees, .{});
247 defer parsed.deinit();
248
249 print("\nJson\n", .{});
250 print("Data - {f}\n", pretty(pretty(employees)));
251 print("{f}\n", .{pretty(parsed.value)});
252
253 const end = std.Io.Timestamp.now(init.io, .cpu_thread);
254 print(
255 "\nTime - {}ms\n",
256 .{(@as(f64, @floatFromInt(end.toMicroseconds())) - @as(f64, @floatFromInt(start.toMicroseconds()))) / 1000.0},
257 );
258}