diff --git a/build.zig b/build.zig index ae23d88..cc0747a 100644 --- a/build.zig +++ b/build.zig @@ -27,26 +27,28 @@ pub fn build(b: *std.Build) !void { // Build static library by default const c_entry = b.path("src/c-api.zig"); - const static_lib = b.addStaticLibrary(.{ - .name = name, + const c_module = b.addModule("plotille-c", .{ .root_source_file = c_entry, .target = target, .optimize = mode, - .version = version, .strip = strip, }); + const static_lib = b.addLibrary(.{ + .name = name, + .root_module = c_module, + .version = version, + .linkage = .static, + }); static_lib.linkLibC(); const installed_static_lib = b.addInstallArtifact(static_lib, .{}); b.getInstallStep().dependOn(&installed_static_lib.step); // Build dynamic library by default (unless static-only is requested) - const shared_lib = b.addSharedLibrary(.{ + const shared_lib = b.addLibrary(.{ .name = name, - .root_source_file = c_entry, - .target = target, - .optimize = mode, + .root_module = c_module, .version = version, - .strip = strip, + .linkage = .dynamic, }); shared_lib.linkLibC(); const installed_shared_lib = b.addInstallArtifact(shared_lib, .{}); @@ -56,8 +58,10 @@ pub fn build(b: *std.Build) !void { const tests = b.addTest(.{ .name = name, .root_module = module, - .filter = filter, }); + if (filter) |f| { + tests.filters = &.{f}; + } const run_tests = b.addRunArtifact(tests); test_step.dependOn(&run_tests.step); } diff --git a/src/c-api.zig b/src/c-api.zig index 7c65a0f..705f51b 100644 --- a/src/c-api.zig +++ b/src/c-api.zig @@ -16,7 +16,7 @@ export fn dots_init() dots.Dots { } export fn dots_str(self: dots.Dots, buf: [*]u8, len: usize) usize { var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{s}", .{self}) catch |err| switch (err) { + std.fmt.format(fbs.writer(), "{f}", .{self}) catch |err| switch (err) { error.NoSpaceLeft => return 0, }; return fbs.pos; @@ -116,7 +116,7 @@ export fn hist_free(h: *CHistogram) void { if (h._internal) |internal| { const hist_ptr: *hist.Histogram = @ptrCast(@alignCast(internal)); - hist_ptr.deinit(); + hist_ptr.deinit(allocator); allocator.destroy(hist_ptr); } @@ -128,7 +128,7 @@ export fn hist_str(h: CHistogram, buf: [*]u8, len: usize) usize { if (h._internal) |internal| { const hist_ptr: *const hist.Histogram = @ptrCast(@alignCast(internal)); var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{}", .{hist_ptr.*}) catch return 0; + std.fmt.format(fbs.writer(), "{f}", .{hist_ptr.*}) catch return 0; return fbs.pos; } return 0; @@ -247,7 +247,7 @@ export fn canvas_str(c: CCanvas, buf: [*]u8, len: usize) usize { if (c._internal) |internal| { const canvas_ptr: *const canvas.Canvas = @ptrCast(@alignCast(internal)); var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{}", .{canvas_ptr.*}) catch return 0; + std.fmt.format(fbs.writer(), "{f}", .{canvas_ptr.*}) catch return 0; return fbs.pos; } return 0; @@ -461,7 +461,7 @@ export fn figure_str(f: CFigure, buf: [*]u8, len: usize) usize { if (f._internal) |internal| { const figure_ptr: *const figure.Figure = @ptrCast(@alignCast(internal)); var fbs = std.io.fixedBufferStream(buf[0..len]); - std.fmt.format(fbs.writer(), "{}", .{figure_ptr.*}) catch return 0; + std.fmt.format(fbs.writer(), "{f}", .{figure_ptr.*}) catch return 0; return fbs.pos; } return 0; diff --git a/src/canvas.zig b/src/canvas.zig index 16e81ed..025d446 100644 --- a/src/canvas.zig +++ b/src/canvas.zig @@ -333,13 +333,8 @@ pub const Canvas = struct { /// Output the canvas to a writer. pub fn format( self: Canvas, - comptime fmt: []const u8, - options: std.fmt.FormatOptions, writer: anytype, ) !void { - // ignored options -> conform to signature - _ = options; - _ = fmt; var h_idx: i18 = self.height - 1; while (h_idx >= 0) : (h_idx -= 1) { try self.printRow(h_idx, writer); @@ -353,7 +348,7 @@ pub const Canvas = struct { const idx: usize = @as(usize, @intCast(row)) * @as(usize, self.width) + w_idx; var d = self.canvas[idx]; d.color.bg = self.bg; - try writer.print("{}", .{d}); + try writer.print("{f}", .{d}); } if (row > 0) { try writer.writeAll(utils.line_separator); @@ -485,8 +480,8 @@ test "simple format canvas" { var c = try Canvas.init(std.testing.allocator, 10, 10, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.point(.{ .x = 0, .y = 0 }, null, null); c.point(.{ .x = 0, .y = 0.5 }, null, null); @@ -499,7 +494,7 @@ test "simple format canvas" { c.point(.{ .x = 0.5, .y = 0 }, null, null); c.point(.{ .x = 0.5, .y = 0.5 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠁⠀⠀⠀⠀⠁⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -518,8 +513,8 @@ test "points with chars in canvas" { var c = try Canvas.init(std.testing.allocator, 10, 10, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.point(.{ .x = 0, .y = 0 }, null, 'x'); c.point(.{ .x = 0, .y = 0.5 }, null, 'o'); @@ -532,7 +527,7 @@ test "points with chars in canvas" { c.point(.{ .x = 0.5, .y = 0 }, null, 'v'); c.point(.{ .x = 0.5, .y = 0.5 }, null, 'b'); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\z⠀⠀⠀⠀u⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -554,8 +549,8 @@ test "format canvas with color" { var c = try Canvas.init(std.testing.allocator, 10, 10, color.Color.by_name(.bright_yellow)); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.point(.{ .x = 0, .y = 0 }, color.Color.by_name(.red), null); c.point(.{ .x = 0, .y = 0.5 }, color.Color.by_name(.black), null); @@ -568,7 +563,7 @@ test "format canvas with color" { c.point(.{ .x = 0.5, .y = 0 }, color.Color.by_name(.black), null); c.point(.{ .x = 0.5, .y = 0.5 }, color.Color.by_name(.blue), null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStrings("\x1b[30;103m⠁\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[30;103m⠁\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m" ++ utils.line_separator ++ "\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m" ++ utils.line_separator ++ "\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m\x1b[103m⠀\x1b[39;49m" ++ utils.line_separator ++ @@ -585,12 +580,12 @@ test "fill char in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.fillChar(.{ .x = 0.5, .y = 0.5 }); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⣿⠀ @@ -602,12 +597,12 @@ test "line in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 0.99, .y = 0.99 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⡜ \\⠀⡜⠀ @@ -619,12 +614,12 @@ test "line in canvas with chars" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 0.99, .y = 0.99 }, null, 'X'); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀X \\⠀⡜⠀ @@ -636,12 +631,12 @@ test "line in one point in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 0.5 }, .{ .x = 0.6, .y = 0.55 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠐⠀ @@ -653,8 +648,8 @@ test "point out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.point(.{ .x = -1, .y = -1 }, null, null); c.point(.{ .x = 2, .y = 2 }, null, null); @@ -666,7 +661,7 @@ test "point out of canvas" { c.point(.{ .x = -0.1, .y = -0.02 }, null, null); c.point(.{ .x = 1, .y = 1 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -678,12 +673,12 @@ test "horizontal line out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = -0.99, .y = 0.5 }, .{ .x = 2, .y = 0.5 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠒⠒⠒ @@ -695,12 +690,12 @@ test "vertical line out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = -0.99 }, .{ .x = 0.5, .y = 2 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⢸⠀ \\⠀⢸⠀ @@ -712,12 +707,12 @@ test "line out of canvas reversed" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 2, .y = 0.5 }, .{ .x = -0.99, .y = 0.5 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠒⠒⠒ @@ -729,12 +724,12 @@ test "vertical line out of canvas reversed" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 2 }, .{ .x = 0.5, .y = -0.99 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⢸⠀ \\⠀⢸⠀ @@ -746,12 +741,12 @@ test "line in canvas small y" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 0.5 }, .{ .x = 0.7, .y = 0.55 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠐⠂ @@ -763,12 +758,12 @@ test "line in canvas small x" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0.5, .y = 0.5 }, .{ .x = 0.55, .y = 0.6 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠘⠀ @@ -780,12 +775,12 @@ test "line completly out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = -0.5, .y = -0.99 }, .{ .x = -0.6, .y = 2 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -797,12 +792,12 @@ test "line flat out of canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = -3, .y = -1 }, .{ .x = 3, .y = 1 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -814,12 +809,12 @@ test "line vertical outside canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = -0.2, .y = -0.2 }, .{ .x = -0.2, .y = 1.2 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -831,12 +826,12 @@ test "simple rect in canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.rect(.{ .x = 0.2, .y = 0.2 }, .{ .x = 0.7, .y = 0.7 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⢀⣀⡀ \\⢸⠀⡇ @@ -848,12 +843,12 @@ test "simple rect in canvas with chars" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.rect(.{ .x = 0.2, .y = 0.2 }, .{ .x = 0.7, .y = 0.7 }, null, 'O'); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\O⣀O \\⢸⠀⡇ @@ -865,12 +860,12 @@ test "rect through canvas horizontally" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.rect(.{ .x = -0.2, .y = 0.2 }, .{ .x = 1.2, .y = 0.8 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠤⠤⠤ \\⠀⠀⠀ @@ -882,12 +877,12 @@ test "rect through canvas vertically" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.rect(.{ .x = 0.2, .y = -0.2 }, .{ .x = 0.8, .y = 1.2 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⢸⠀⡇ \\⢸⠀⡇ @@ -899,12 +894,12 @@ test "rect outside canvas" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.rect(.{ .x = -0.2, .y = -0.2 }, .{ .x = 1.2, .y = 1.2 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -916,12 +911,12 @@ test "rect in large Canvas" { var c = try Canvas.init(std.testing.allocator, 255, 255, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.rect(.{ .x = -0.2, .y = -0.2 }, .{ .x = 1.2, .y = 1.2 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); const extra = if (@import("builtin").target.os.tag == .windows) 254 else 0; try expectEqual(@as(usize, 195329 + extra), list.items.len); // 3 chars per unicode, 254 linebreaks } @@ -930,12 +925,12 @@ test "text inside canvas" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.text(.{ .x = 0.1, .y = 0.5 }, "Hello", null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀Hello⠀⠀⠀⠀ @@ -947,12 +942,12 @@ test "text inside canvas too large" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.text(.{ .x = 0.1, .y = 0.5 }, "Hello World, how are you?", null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀Hello Wor @@ -964,13 +959,13 @@ test "text inside canvas move out left" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); // 5 chars back c.text(.{ .x = -0.5, .y = 0.5 }, "Hello World, how are you?", null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\ World, ho @@ -982,13 +977,13 @@ test "text below canvas" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); // 5 chars back c.text(.{ .x = 0.1, .y = -0.5 }, "Hello", null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -1000,13 +995,13 @@ test "text above canvas" { var c = try Canvas.init(std.testing.allocator, 10, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); // 5 chars back c.text(.{ .x = 0.1, .y = 1.5 }, "Hello", null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ \\⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ @@ -1018,12 +1013,12 @@ test "points with very large coordinates" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.point(.{ .x = 1e200, .y = 1e200 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -1034,12 +1029,12 @@ test "points with very small coordinates" { var c = try Canvas.init(std.testing.allocator, 3, 3, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); c.point(.{ .x = -1e200, .y = -1e200 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); try expectEqualStringsNormalized( \\⠀⠀⠀ \\⠀⠀⠀ @@ -1051,12 +1046,12 @@ test "canvas with large height" { var c = try Canvas.init(std.testing.allocator, 128, 65535, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 1, .y = 1 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); const extra = if (@import("builtin").target.os.tag == .windows) 65534 else 0; try expectEqual(@as(usize, 25_230_974 + extra), list.items.len); // 3 chars per unicode, 65534 linebreaks } @@ -1065,12 +1060,12 @@ test "canvas with large width" { var c = try Canvas.init(std.testing.allocator, 65535, 128, color.Color.no_color()); defer c.deinit(std.testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); try c.line(.{ .x = 0, .y = 0 }, .{ .x = 1, .y = 1 }, null, null); - try list.writer().print("{}", .{c}); + try list.writer(std.testing.allocator).print("{f}", .{c}); const extra = if (@import("builtin").target.os.tag == .windows) 127 else 0; try expectEqual(@as(usize, 25_165_567 + extra), list.items.len); // 3 chars per unicode, 127 linebreaks } diff --git a/src/dots.zig b/src/dots.zig index 8304c36..30e416e 100644 --- a/src/dots.zig +++ b/src/dots.zig @@ -44,13 +44,8 @@ pub const Dots = extern struct { pub fn format( self: Dots, - comptime fmt: []const u8, - options: std.fmt.FormatOptions, writer: anytype, ) !void { - // ignored options -> conform to signature - _ = options; - _ = fmt; var buff: [3]u8 = undefined; var v: u21 = 0x2800; @@ -95,17 +90,17 @@ test "test clear and full char" { var d = Dots{}; - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.fill(); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⣿", fbs.getWritten()); fbs.reset(); d.clear(); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); } @@ -116,79 +111,79 @@ test "set and unset individual vals" { var d = Dots{}; - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(0, 0); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⡀", fbs.getWritten()); fbs.reset(); d.unset(0, 0); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(0, 1); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠄", fbs.getWritten()); fbs.reset(); d.unset(0, 1); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(0, 2); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠂", fbs.getWritten()); fbs.reset(); d.unset(0, 2); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(0, 3); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠁", fbs.getWritten()); fbs.reset(); d.unset(0, 3); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(1, 0); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⢀", fbs.getWritten()); fbs.reset(); d.unset(1, 0); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(1, 1); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠠", fbs.getWritten()); fbs.reset(); d.unset(1, 1); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(1, 2); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠐", fbs.getWritten()); fbs.reset(); d.unset(1, 2); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); d.set(1, 3); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠈", fbs.getWritten()); fbs.reset(); d.unset(1, 3); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); } @@ -201,24 +196,24 @@ test "colored dots" { var d = Dots{}; d.set(0, 0); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⡀", fbs.getWritten()); fbs.reset(); d.color.fg = color.Color.by_name(.red); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqual(fbs.pos, 16); try expectEqualStrings("\x1b[31m⡀\x1b[39;49m", fbs.getWritten()); fbs.reset(); d.color.bg = color.Color.by_lookup(123); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqual(fbs.pos, 25); try expectEqualStrings("\x1b[31;48;5;123m⡀\x1b[39;49m", fbs.getWritten()); fbs.reset(); d.color.fg = color.Color.by_rgb(1, 22, 133); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqual(fbs.pos, 36); try expectEqualStrings("\x1b[38;2;1;22;133;48;5;123m⡀\x1b[39;49m", fbs.getWritten()); fbs.reset(); @@ -231,12 +226,12 @@ test "set / unset char" { var d = Dots{}; d.char = 'x'; - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("x", fbs.getWritten()); fbs.reset(); d.clear(); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠀", fbs.getWritten()); fbs.reset(); } @@ -250,7 +245,7 @@ test "color char" { d.char = 'x'; d.color.fg = color.Color.by_rgb(111, 222, 255); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("\x1b[38;2;111;222;255mx\x1b[39;49m", fbs.getWritten()); fbs.reset(); } @@ -262,22 +257,22 @@ test "set char and dots" { var d = Dots{}; d.char = 'x'; - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("x", fbs.getWritten()); fbs.reset(); d.set(0, 1); - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("x", fbs.getWritten()); fbs.reset(); d.char = 0; - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("⠄", fbs.getWritten()); fbs.reset(); d.char = 'o'; - try std.fmt.format(fbs.writer(), "{s}", .{d}); + try std.fmt.format(fbs.writer(), "{f}", .{d}); try expectEqualStrings("o", fbs.getWritten()); fbs.reset(); } diff --git a/src/figure.zig b/src/figure.zig index 2ffd559..c7b77b5 100644 --- a/src/figure.zig +++ b/src/figure.zig @@ -55,10 +55,10 @@ pub const Figure = struct { .x_label = try allocator.dupe(u8, "X"), .y_label = try allocator.dupe(u8, "Y"), ._canvas = null, - ._plots = std.ArrayList(Plot).init(allocator), - ._histograms = std.ArrayList(Histogram).init(allocator), - ._texts = std.ArrayList(Text).init(allocator), - ._spans = std.ArrayList(Span).init(allocator), + ._plots = .{}, + ._histograms = .{}, + ._texts = .{}, + ._spans = .{}, .allocator = allocator, }; } @@ -69,19 +69,19 @@ pub const Figure = struct { for (self._plots.items) |*p| { p.deinit(self.allocator); } - self._plots.deinit(); + self._plots.deinit(self.allocator); for (self._histograms.items) |*h| { - h.deinit(); + h.deinit(self.allocator); } - self._histograms.deinit(); + self._histograms.deinit(self.allocator); for (self._texts.items) |*t| { t.deinit(self.allocator); } - self._texts.deinit(); + self._texts.deinit(self.allocator); if (self._canvas) |cvs| { cvs.deinit(self.allocator); } - self._spans.deinit(); + self._spans.deinit(self.allocator); } pub fn plot(self: *Figure, xs: []const f64, ys: []const f64, opts: struct { @@ -92,7 +92,7 @@ pub const Figure = struct { var p = try Plot.init(self.allocator, xs, ys, opts.lc, true, opts.label, opts.marker); errdefer p.deinit(self.allocator); - try self._plots.append(p); + try self._plots.append(self.allocator, p); } pub fn scatter(self: *Figure, xs: []const f64, ys: []const f64, opts: struct { @@ -103,7 +103,7 @@ pub const Figure = struct { var p = try Plot.init(self.allocator, xs, ys, opts.lc, false, opts.label, opts.marker); errdefer p.deinit(self.allocator); - try self._plots.append(p); + try self._plots.append(self.allocator, p); } pub fn histogram(self: *Figure, xs: []const f64, bins: usize, lc: ?color.Color) !void { @@ -113,9 +113,9 @@ pub const Figure = struct { bins, if (lc) |c| c else color.Color.no_color(), ); - errdefer h.deinit(); + errdefer h.deinit(self.allocator); - try self._histograms.append(h); + try self._histograms.append(self.allocator, h); } pub fn text(self: *Figure, x: f64, y: f64, str: []const u8, lc: ?color.Color) !void { @@ -128,7 +128,7 @@ pub const Figure = struct { ); errdefer t.deinit(self.allocator); - try self._texts.append(t); + try self._texts.append(self.allocator, t); } pub fn axvline(self: *Figure, x: f64, opts: struct { @@ -140,7 +140,7 @@ pub const Figure = struct { assert(0 <= opts.ymin and opts.ymin <= 1); assert(0 <= opts.ymax and opts.ymax <= 1); assert(opts.ymin <= opts.ymax); - try self._spans.append(Span{ + try self._spans.append(self.allocator, Span{ .xmin = x, .xmax = x, .ymin = opts.ymin, @@ -160,7 +160,7 @@ pub const Figure = struct { assert(0 <= opts.ymax and opts.ymax <= 1); assert(xmin <= xmax); assert(opts.ymin <= opts.ymax); - try self._spans.append(Span{ + try self._spans.append(self.allocator, Span{ .xmin = xmin, .xmax = xmax, .ymin = opts.ymin, @@ -178,7 +178,7 @@ pub const Figure = struct { assert(0 <= opts.xmin and opts.xmin <= 1); assert(0 <= opts.xmax and opts.xmax <= 1); assert(opts.xmin <= opts.xmax); - try self._spans.append(Span{ + try self._spans.append(self.allocator, Span{ .xmin = opts.xmin, .xmax = opts.xmax, .ymin = y, @@ -198,7 +198,7 @@ pub const Figure = struct { assert(0 <= opts.xmax and opts.xmax <= 1); assert(ymin <= ymax); assert(opts.xmin <= opts.xmax); - try self._spans.append(Span{ + try self._spans.append(self.allocator, Span{ .xmin = opts.xmin, .xmax = opts.xmax, .ymin = ymin, @@ -232,12 +232,8 @@ pub const Figure = struct { /// Output the figure to a writer. pub fn format( self: Figure, - comptime fmt: []const u8, - options: std.fmt.FormatOptions, writer: anytype, ) !void { - _ = fmt; - _ = options; // You need to prepare the canvas before writing the figure. assert(self._canvas != null); assert(self._canvas.?.width == self.width); @@ -279,18 +275,18 @@ pub const Figure = struct { assert(self.xmin < self.xmax); const x_delta = @abs(self.xmax - self.xmin) / @as(f64, @floatFromInt(self.width)); - try writer.writeByteNTimes('-', 11); + try writer.splatByteAll('-', 11); try writer.writeAll("|-"); var col: usize = 0; while (col < self.width / 10) : (col += 1) { try writer.writeAll("|---------"); } try writer.writeAll("|"); - try writer.writeByteNTimes('-', self.width % 10); + try writer.splatByteAll('-', self.width % 10); try writer.print("-> ({s})" ++ utils.line_separator, .{self.x_label}); - try writer.writeByteNTimes(' ', 11); + try writer.splatByteAll(' ', 11); try writer.writeAll("| "); col = 0; while (col < self.width / 10 + 1) : (col += 1) { @@ -376,8 +372,8 @@ pub const Figure = struct { }; } - fn deinit(self: *Histogram) void { - self.histogram.deinit(); + fn deinit(self: *Histogram, allocator: mem.Allocator) void { + self.histogram.deinit(allocator); } fn write(self: Histogram, cvs: *canvas.Canvas) !void { @@ -504,10 +500,10 @@ test "working test" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\3.000 | @@ -527,7 +523,7 @@ test "working test" { // force colors terminfo.TermInfo.testing(); - std.debug.print("\n{}\n", .{fig}); + std.debug.print("\n{f}\n", .{fig}); } test "figure with axvline center" { @@ -539,10 +535,10 @@ test "figure with axvline center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -570,10 +566,10 @@ test "figure with axvline center center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -601,10 +597,10 @@ test "figure with axvline left" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -632,10 +628,10 @@ test "figure with axvline right" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -663,10 +659,10 @@ test "figure with axvspan border" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -694,10 +690,10 @@ test "figure with axvspan center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -725,10 +721,10 @@ test "figure with axvspan center center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -756,10 +752,10 @@ test "figure with axhline center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -787,10 +783,10 @@ test "figure with axhline center center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -818,10 +814,10 @@ test "figure with axhline bottom" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -849,10 +845,10 @@ test "figure with axhline top" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -880,10 +876,10 @@ test "figure with axhspan border" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -911,10 +907,10 @@ test "figure with axhspan center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | @@ -942,10 +938,10 @@ test "figure with axhspan center center" { try fig.prepare(); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{fig}); + try list.writer(std.testing.allocator).print("{f}", .{fig}); try expectEqualStringsNormalized( \\ Y ^ \\1.000 | diff --git a/src/hist.zig b/src/hist.zig index 500dea3..d7adc24 100644 --- a/src/hist.zig +++ b/src/hist.zig @@ -11,6 +11,18 @@ const expectEqualStringsNormalized = utils.expectEqualStringsNormalized; const utils = @import("./utils.zig"); +pub const HistogramFormatter = struct { + hist: Histogram, + width: usize, + + pub fn format( + self: HistogramFormatter, + writer: anytype, + ) !void { + return self.hist.formatWithWidth(writer, self.width); + } +}; + pub const Histogram = struct { counts: ArrayList(u32), bins: ArrayList(f64), @@ -28,11 +40,11 @@ pub const Histogram = struct { .bins = try ArrayList(f64).initCapacity(allocator, bins + 1), .delta = delta, }; - errdefer h.counts.deinit(); - errdefer h.bins.deinit(); + errdefer h.counts.deinit(allocator); + errdefer h.bins.deinit(allocator); // count values into bins - try h.counts.appendNTimes(0, bins); + try h.counts.appendNTimes(allocator, 0, bins); for (values) |value| { const val_delta = value - x.min; const val_idx = @min(bins - 1, @as(usize, @intFromFloat(val_delta / xwidth))); @@ -40,7 +52,7 @@ pub const Histogram = struct { } // values for bins - try h.bins.appendNTimes(0, bins + 1); + try h.bins.appendNTimes(allocator, 0, bins + 1); var idx: usize = 0; while (idx < bins + 1) : (idx += 1) { h.bins.items[idx] = @as(f64, @floatFromInt(idx)) * xwidth + x.min; @@ -49,19 +61,29 @@ pub const Histogram = struct { return h; } - pub fn deinit(self: *Histogram) void { - self.bins.deinit(); - self.counts.deinit(); + pub fn deinit(self: *Histogram, allocator: Allocator) void { + self.bins.deinit(allocator); + self.counts.deinit(allocator); + } + + /// Create a formatter with a custom width + pub fn withWidth(self: Histogram, width: usize) HistogramFormatter { + return HistogramFormatter{ .hist = self, .width = width }; } /// Output the Histogram to a writer. pub fn format( self: Histogram, - comptime fmt: []const u8, - options: std.fmt.FormatOptions, writer: anytype, ) !void { - const width = options.width orelse 80; + return self.formatWithWidth(writer, 80); + } + + fn formatWithWidth( + self: Histogram, + writer: anytype, + width: usize, + ) !void { const h_max = lbl: { var count: u32 = 1; for (self.counts.items) |item| { @@ -75,20 +97,15 @@ pub const Histogram = struct { const lasts = [_][]const u8{ "", "⠂", "⠆", "⠇", "⡇", "⡗", "⡷", "⡿" }; try writer.writeAll(" bucket | "); - try writer.writeByteNTimes('_', width); + try writer.splatByteAll('_', width); try writer.writeAll(" Total Counts" ++ utils.line_separator); var widx: usize = 0; for (self.counts.items, 0..) |count, idx| { - if (fmt.len != 0) { - const fmt_with_colon = comptime fmt[0..1] ++ ":" ++ fmt[1..]; - try writer.print("[{" ++ fmt_with_colon ++ "}, {" ++ fmt_with_colon ++ "}) | ", .{ self.bins.items[idx], self.bins.items[idx + 1] }); + if (self.delta < 1 or self.delta > 1000) { + try writer.print("[{e:<8.1}, {e:<8.1}) | ", .{ self.bins.items[idx], self.bins.items[idx + 1] }); } else { - if (self.delta < 1 or self.delta > 1000) { - try writer.print("[{e:<8.1}, {e:<8.1}) | ", .{ self.bins.items[idx], self.bins.items[idx + 1] }); - } else { - try writer.print("[{d:<8.3}, {d:<8.3}) | ", .{ self.bins.items[idx], self.bins.items[idx + 1] }); - } + try writer.print("[{d:<8.3}, {d:<8.3}) | ", .{ self.bins.items[idx], self.bins.items[idx + 1] }); } const height = width * 8 * count / h_max; widx = 0; @@ -170,7 +187,7 @@ test "Extrema of multiple similar values" { test "Histogram of empty list" { const values = [_]f64{}; var h = try Histogram.init(testing.allocator, &values, 2); - defer h.deinit(); + defer h.deinit(testing.allocator); try expectEqualSlices(f64, h.bins.items, &([_]f64{ 0, 0.5, 1 })); try expectEqualSlices(u32, h.counts.items, &([_]u32{ 0, 0 })); @@ -179,7 +196,7 @@ test "Histogram of empty list" { test "Histogram of list of one" { const values = [_]f64{42}; var h = try Histogram.init(testing.allocator, &values, 2); - defer h.deinit(); + defer h.deinit(testing.allocator); try expectEqualSlices(f64, h.bins.items, &([_]f64{ 41.5, 42, 42.5 })); try expectEqualSlices(u32, h.counts.items, &([_]u32{ 0, 1 })); @@ -188,7 +205,7 @@ test "Histogram of list of one" { test "Histogram of list of two" { const values = [_]f64{ 42, -42 }; var h = try Histogram.init(testing.allocator, &values, 2); - defer h.deinit(); + defer h.deinit(testing.allocator); try expectEqualSlices(f64, h.bins.items, &([_]f64{ -42, 0, 42 })); try expectEqualSlices(u32, h.counts.items, &([_]u32{ 1, 1 })); @@ -197,7 +214,7 @@ test "Histogram of list of two" { test "Histogram of list of many" { const values = [_]f64{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12 }; var h = try Histogram.init(testing.allocator, &values, 2); - defer h.deinit(); + defer h.deinit(testing.allocator); try expectEqualSlices(f64, h.bins.items, &([_]f64{ 1, 6.5, 12 })); try expectEqualSlices(u32, h.counts.items, &([_]u32{ 6, 5 })); @@ -206,7 +223,7 @@ test "Histogram of list of many" { test "Histogram of list of many with one bin for each" { const values = [_]f64{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12 }; var h = try Histogram.init(testing.allocator, &values, 12); - defer h.deinit(); + defer h.deinit(testing.allocator); try expectEqualSlices(f64, h.bins.items, &([_]f64{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 })); try expectEqualSlices(u32, h.counts.items, &([_]u32{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 })); @@ -215,7 +232,7 @@ test "Histogram of list of many with one bin for each" { test "Histogram of list of many with one bin for each negative" { const values = [_]f64{ 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -12 }; var h = try Histogram.init(testing.allocator, &values, 12); - defer h.deinit(); + defer h.deinit(testing.allocator); try expectEqualSlices(f64, h.bins.items, &([_]f64{ -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0 })); try expectEqualSlices(u32, h.counts.items, &([_]u32{ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 })); @@ -224,12 +241,12 @@ test "Histogram of list of many with one bin for each negative" { test "write simple Histogram" { const values = [_]f64{ 0, 1, 2, 3, 4, 5, 5, 5, 8, 9, 10, 12 }; var h = try Histogram.init(testing.allocator, &values, 12); - defer h.deinit(); + defer h.deinit(testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{:60}", .{h}); + try list.writer(std.testing.allocator).print("{f}", .{h.withWidth(60)}); try expectEqualStringsNormalized( \\ bucket | ____________________________________________________________ Total Counts @@ -258,12 +275,12 @@ test "write random Histogram" { values[i] = random.floatNorm(f64); } var h = try Histogram.init(testing.allocator, &values, 10); - defer h.deinit(); + defer h.deinit(testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{:40}", .{h}); + try list.writer(std.testing.allocator).print("{f}", .{h.withWidth(40)}); try expectEqualStringsNormalized( \\ bucket | ________________________________________ Total Counts @@ -290,12 +307,12 @@ test "write large random Histogram" { values[i] = 1_000_000 * random.floatNorm(f64); } var h = try Histogram.init(testing.allocator, &values, 10); - defer h.deinit(); + defer h.deinit(testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{e<8.1}", .{h}); + try list.writer(std.testing.allocator).print("{f}", .{h}); try expectEqualStringsNormalized( \\ bucket | ________________________________________________________________________________ Total Counts @@ -322,12 +339,12 @@ test "write small random Histogram" { values[i] = random.float(f64) / 1_000_000; } var h = try Histogram.init(testing.allocator, &values, 10); - defer h.deinit(); + defer h.deinit(testing.allocator); - var list = std.ArrayList(u8).init(std.testing.allocator); - defer list.deinit(); + var list: std.ArrayList(u8) = .{}; + defer list.deinit(std.testing.allocator); - try list.writer().print("{}", .{h}); + try list.writer(std.testing.allocator).print("{f}", .{h}); try expectEqualStringsNormalized( \\ bucket | ________________________________________________________________________________ Total Counts diff --git a/src/terminfo.zig b/src/terminfo.zig index 78553ee..68c9dc0 100644 --- a/src/terminfo.zig +++ b/src/terminfo.zig @@ -73,7 +73,7 @@ pub const TermInfo = extern struct { /// Read out environment variables, hence the allocator. pub fn detect(allocator: std.mem.Allocator) !void { - const stdout_tty = std.io.getStdOut().isTty(); + const stdout_tty = std.posix.isatty(std.posix.STDOUT_FILENO); const no_color = isNoColorSet(allocator); const force_color = try forceColors(allocator); const color_mode = try getColorMode(allocator);