A pretty printer for zig
zig

pretty arrays

altagos.dev 99153376 0ad06c6f

verified
+100 -16
+23 -4
example/main.zig
··· 5 5 const pretty = pretty_mod.pretty; 6 6 const Pretty = pretty_mod.PrettyWithOptions; 7 7 8 - pub const pretty_options = pretty_mod.Options{ .always_show_type_names = true }; 8 + pub const pretty_options = pretty_mod.Options{ 9 + .always_show_type_names = true, 10 + }; 9 11 10 12 const Hello = enum { world, developer }; 11 13 ··· 30 32 }; 31 33 32 34 const ChildC = struct { 33 - person: Person, 35 + person: [2]Person, 34 36 }; 35 37 36 38 const ErrorSet = error{ OutOfMemory, WriteFailed }; ··· 88 90 const person = Person{ .age = 13, .gender = null }; 89 91 90 92 const nested = Nested{ 91 - .a = .{ .child = .{ .person = person } }, 93 + .a = .{ .child = .{ .person = .{ person, Person{ 94 + .age = 42, 95 + .gender = .nonbinary, 96 + } } } }, 92 97 .b = .{ .hello = .world }, 93 98 }; 94 99 95 100 print("\nStructs\n", .{}); 96 101 print("Pretty simple struct - {f}\n", .{pretty(person)}); 97 102 print( 98 - "Pretty simple inlined struct - {f}\n", 103 + "Pretty simple inline struct - {f}\n", 99 104 .{Pretty(Person, .{ .inline_structs = true }).init(person)}, 100 105 ); 101 106 print("Pretty nested struct - {f}\n", .{pretty(nested)}); 107 + 108 + print("\nArrays\n", .{}); 109 + print("Array of floats - {f}\n", .{pretty([_]f32{ 0.1, 0.2, 0.3 })}); 110 + print( 111 + "Array of floats inline - {f}\n", 112 + .{Pretty([3]f32, .{ .inline_arrays = true }).init([_]f32{ 0.1, 0.2, 0.3 })}, 113 + ); 114 + print( 115 + "Array of floats inline with indices - {f}\n", 116 + .{Pretty([3]f32, .{ 117 + .inline_arrays = true, 118 + .always_show_index = true, 119 + }).init([_]f32{ 0.1, 0.2, 0.3 })}, 120 + ); 102 121 103 122 const eu_error: Result = error.OutOfMemory; 104 123 const eu_ok: Result = .world;
+77 -12
pretty.zig
··· 6 6 7 7 pub const Options = struct { 8 8 indent_width: comptime_int = 2, 9 + 10 + inline_arrays: bool = false, 11 + always_show_index: bool = false, 12 + 9 13 inline_structs: bool = false, 10 14 11 15 show_type_names: bool = true, 12 16 always_show_type_names: bool = false, 17 + 18 + treat_u8_arrays_as_strings: bool = true, 13 19 14 20 theme: Theme = .{}, 15 21 }; ··· 28 34 29 35 field_name_type_sep: []const u8 = ": ", 30 36 type_value_sep: []const u8 = " = ", 37 + index_value_sep: []const u8 = " = ", 38 + 39 + index_open: []const u8 = "[", 40 + index_close: []const u8 = "]", 31 41 32 42 color_dim: Io.Terminal.Color = .dim, 33 43 color_field: Io.Terminal.Color = .green, ··· 93 103 tty: Io.Terminal, 94 104 95 105 depth: usize = 0, 96 - 97 - indent_level: usize = 0, 98 106 99 107 pub inline fn print( 100 108 this: *const Runtime, ··· 128 136 const Context = struct { 129 137 depth: comptime_int = 0, 130 138 131 - indent_level: comptime_int = 0, 132 - 133 139 options: Options, 134 140 exited_comptime: bool = false, 135 141 ··· 148 154 comptime ctx: Context, 149 155 run: *Runtime, 150 156 value: T, 151 - opts: InnerFmtOptions, 157 + comptime opts: InnerFmtOptions, 152 158 ) error{WriteFailed}!void { 153 159 const info = @typeInfo(T); 154 160 ··· 177 183 .error_set => formatErrorSet(ctx, run, value), 178 184 .error_union => formatErrorUnion(ctx, run, value), 179 185 180 - // TODO: .array => |arr| {}, 186 + .array => |arr| formatArray(ctx, arr, run, value), 181 187 // TODO: .pointer => |ptr| {}, 182 188 // TODO: .vector => |vec| {}, 183 189 ··· 255 261 ) !void { 256 262 const next_ctx = Context{ 257 263 .depth = ctx.depth + 1, 258 - .indent_level = ctx.indent_level + 1, 259 264 .exited_comptime = ctx.exited_comptime, 260 265 .options = ctx.options, 261 266 }; ··· 268 273 269 274 comptime var index = 0; 270 275 inline for (st.fields) |field| { 271 - indent(next_ctx, run); 272 - if (index != 0 and ctx.options.inline_structs) try run.write(", "); 276 + indent(next_ctx, next_ctx.options.inline_structs, run); 277 + if (index != 0 and ctx.options.inline_structs) { 278 + run.setColor(ctx, .dim); 279 + try run.write(", "); 280 + run.resetColor(); 281 + } 273 282 274 283 run.setColor(ctx, .field); 275 - try run.write("." ++ field.name ++ ctx.options.theme.field_name_type_sep); 284 + try run.write("." ++ field.name ++ 285 + ctx.options.theme.field_name_type_sep); 276 286 run.resetColor(); 277 287 278 288 try innerFmt(field.type, next_ctx, run, @field(value, field.name), .{}); ··· 287 297 } 288 298 } 289 299 300 + inline fn formatArray( 301 + comptime ctx: Context, 302 + comptime arr: Type.Array, 303 + run: *Runtime, 304 + value: anytype, 305 + ) !void { 306 + const next_ctx = Context{ 307 + .depth = ctx.depth + 1, 308 + .exited_comptime = ctx.exited_comptime, 309 + .options = ctx.options, 310 + }; 311 + 312 + if (ctx.options.inline_arrays) { 313 + run.setColor(ctx, .dim); 314 + try run.write("{ "); 315 + run.resetColor(); 316 + } 317 + 318 + comptime var index = 0; 319 + inline for (value) |val| { 320 + indent( 321 + next_ctx, 322 + next_ctx.options.inline_arrays, 323 + run, 324 + ); 325 + 326 + run.setColor(ctx, .dim); 327 + if (index != 0 and ctx.options.inline_arrays) 328 + try run.write(", "); 329 + 330 + if (!ctx.options.inline_arrays or ctx.options.always_show_index) { 331 + try run.write(ctx.options.theme.index_open); 332 + try run.print("{}", .{index}); 333 + try run.write(ctx.options.theme.index_close ++ 334 + ctx.options.theme.index_value_sep); 335 + } 336 + 337 + run.resetColor(); 338 + 339 + try innerFmt(arr.child, next_ctx, run, val, .{ .skip_type_name = true }); 340 + 341 + index += 1; 342 + } 343 + 344 + if (ctx.options.inline_arrays) { 345 + run.setColor(ctx, .dim); 346 + try run.write(" }"); 347 + run.resetColor(); 348 + } 349 + } 350 + 290 351 inline fn formatErrorSet( 291 352 comptime ctx: Context, 292 353 run: *const Runtime, ··· 348 409 run.resetColor(); 349 410 } 350 411 351 - inline fn indent(comptime ctx: Context, run: *const Runtime) void { 352 - if (ctx.options.inline_structs) return; 412 + inline fn indent( 413 + comptime ctx: Context, 414 + comptime inline_option: bool, 415 + run: *const Runtime, 416 + ) void { 417 + if (inline_option) return; 353 418 354 419 const text: [ctx.depth * ctx.options.indent_width]u8 = @splat(' '); 355 420 run.write("\n" ++ text) catch {};