tangled
alpha
login
or
join now
altagos.dev
/
pretty
0
fork
atom
A pretty printer for zig
zig
0
fork
atom
overview
issues
pulls
pipelines
pretty structs
altagos.dev
1 month ago
85e44017
c195ec1c
verified
This commit was signed with the committer's
known signature
.
altagos.dev
SSH Key Fingerprint:
SHA256:UbTjEcCZlc6GzQWLCuDK3D//HESWD2xFPkzue9XMras=
+94
-5
2 changed files
expand all
collapse all
unified
split
example
main.zig
pretty.zig
+40
-1
example/main.zig
···
9
9
10
10
const Hello = enum { world, developer };
11
11
12
12
+
const Gender = enum(u8) { male, female, nonbinary, other, _ };
13
13
+
14
14
+
const Person = struct {
15
15
+
age: u8,
16
16
+
gender: ?Gender,
17
17
+
};
18
18
+
19
19
+
const Nested = struct {
20
20
+
a: ChildA,
21
21
+
b: ChildB,
22
22
+
};
23
23
+
24
24
+
const ChildA = struct {
25
25
+
child: ChildC,
26
26
+
};
27
27
+
28
28
+
const ChildB = struct {
29
29
+
hello: Hello,
30
30
+
};
31
31
+
32
32
+
const ChildC = struct {
33
33
+
person: Person,
34
34
+
};
35
35
+
12
36
pub fn main(init: std.process.Init) !void {
13
37
_ = init;
14
38
···
20
44
print("Boolean false - {f}\n", .{pretty(false)});
21
45
print(
22
46
"Boolean true always with type name - {f}\n",
23
23
-
.{Pretty(bool, .{ .always_show_type_names = true, .type_value_seperator = ": " }).init(true)},
47
47
+
.{Pretty(bool, .{ .always_show_type_names = true, .type_value_sep = ": " }).init(true)},
24
48
);
25
49
26
50
print("\nUnsigned Integers\n", .{});
···
54
78
print("\nOptionals\n", .{});
55
79
print("Pretty optional = null - {f}\n", .{pretty(opt_null)});
56
80
print("Pretty optional = not null - {f}\n", .{pretty(opt_not_null)});
81
81
+
82
82
+
const person = Person{ .age = 13, .gender = null };
83
83
+
84
84
+
const nested = Nested{
85
85
+
.a = .{ .child = .{ .person = person } },
86
86
+
.b = .{ .hello = .world },
87
87
+
};
88
88
+
89
89
+
print("\nStructs\n", .{});
90
90
+
print("Pretty simple struct - {f}\n", .{pretty(person)});
91
91
+
print(
92
92
+
"Pretty simple inlined struct - {f}\n",
93
93
+
.{Pretty(Person, .{ .inline_structs = true }).init(person)},
94
94
+
);
95
95
+
print("Pretty nested struct - {f}\n", .{pretty(nested)});
57
96
}
+54
-4
pretty.zig
···
6
6
7
7
pub const Options = struct {
8
8
indent_width: comptime_int = 2,
9
9
+
inline_structs: bool = false,
9
10
10
11
show_type_names: bool = true,
11
11
-
always_show_type_names: bool = true,
12
12
+
always_show_type_names: bool = false,
12
13
13
14
field_name_type_sep: []const u8 = ": ",
14
15
type_value_sep: []const u8 = " = ",
···
28
29
const global = struct {
29
30
var tty: ?Io.Terminal = null;
30
31
};
32
32
+
const cctx: ComptimeContext = ComptimeContext{ .options = options };
31
33
32
34
return struct {
33
35
value: T,
···
46
48
global.tty.?.writer = w;
47
49
}
48
50
49
49
-
const comp_ctx = ComptimeContext{ .options = options };
50
50
-
const run_ctx = RuntimeContext{
51
51
+
const rctx = RuntimeContext{
51
52
.out = w,
52
53
.tty = global.tty.?,
53
54
};
54
55
55
55
-
return innerFmt(T, comp_ctx, run_ctx, this.value, .{});
56
56
+
return innerFmt(T, cctx, rctx, this.value, .{});
56
57
}
57
58
};
58
59
}
···
128
129
=> formatValue(rctx, value),
129
130
130
131
.optional => |opt| formatOptional(opt.child, cctx, rctx, value),
132
132
+
.@"struct" => |st| formatStruct(T, st, cctx, rctx, value),
131
133
132
134
else => {
133
135
rctx.setColor(.red);
···
184
186
formatNull(rctx);
185
187
}
186
188
189
189
+
inline fn formatStruct(
190
190
+
comptime T: type,
191
191
+
comptime st: Type.Struct,
192
192
+
comptime cctx: ComptimeContext,
193
193
+
rctx: RuntimeContext,
194
194
+
value: T,
195
195
+
) !void {
196
196
+
const next_cctx = ComptimeContext{
197
197
+
.depth = cctx.depth + 1,
198
198
+
.indent_level = cctx.indent_level + 1,
199
199
+
.exited_comptime = cctx.exited_comptime,
200
200
+
.options = cctx.options,
201
201
+
};
202
202
+
203
203
+
if (cctx.options.inline_structs) {
204
204
+
rctx.setColor(.dim);
205
205
+
try rctx.write(".{ ");
206
206
+
rctx.resetColor();
207
207
+
}
208
208
+
209
209
+
comptime var index: comptime_int = 0;
210
210
+
inline for (st.fields) |field| {
211
211
+
indent(next_cctx, rctx);
212
212
+
if (index != 0 and cctx.options.inline_structs) try rctx.write(", ");
213
213
+
214
214
+
rctx.setColor(.green);
215
215
+
try rctx.write("." ++ field.name ++ cctx.options.field_name_type_sep);
216
216
+
rctx.resetColor();
217
217
+
218
218
+
try innerFmt(field.type, next_cctx, rctx, @field(value, field.name), .{});
219
219
+
220
220
+
index += 1;
221
221
+
}
222
222
+
223
223
+
if (cctx.options.inline_structs) {
224
224
+
rctx.setColor(.dim);
225
225
+
try rctx.write(" }");
226
226
+
rctx.resetColor();
227
227
+
}
228
228
+
}
229
229
+
187
230
inline fn formatType(ctx: RuntimeContext, value: type) !void {
188
231
ctx.setColor(.bright_blue);
189
232
ctx.setColor(.bold);
···
196
239
try ctx.print("{}", .{value});
197
240
ctx.resetColor();
198
241
}
242
242
+
243
243
+
inline fn indent(comptime cctx: ComptimeContext, rctx: RuntimeContext) void {
244
244
+
if (cctx.options.inline_structs) return;
245
245
+
246
246
+
const text: [cctx.depth * cctx.options.indent_width]u8 = @splat(' ');
247
247
+
rctx.write("\n" ++ text) catch {};
248
248
+
}