feature. See also
. The project being documented here (as the example) is the Zig library itself.
testing.BytesDiffer
const BytesDiffer = struct
File
Code
const BytesDiffer = struct {
expected: []const u8,
actual: []const u8,
terminal_mode: Io.Terminal.Mode,
pub fn write(self: BytesDiffer, writer: *Io.Writer) !void {
var expected_iterator = std.mem.window(u8, self.expected, 16, 16);
var row: usize = 0;
while (expected_iterator.next()) |chunk| {
var diffs: std.bit_set.Integer(16) = .{ .mask = 0 };
for (chunk, 0..) |byte, col| {
const absolute_byte_index = col + row * 16;
const diff = if (absolute_byte_index < self.actual.len) self.actual[absolute_byte_index] != byte else true;
if (diff) diffs.set(col);
try self.writeDiff(writer, "{X:0>2} ", .{byte}, diff);
if (col == 7) try writer.writeByte(' ');
}
try writer.writeByte(' ');
if (chunk.len < 16) {
var missing_columns = (16 - chunk.len) * 3;
if (chunk.len < 8) missing_columns += 1;
try writer.splatByteAll(' ', missing_columns);
}
for (chunk, 0..) |byte, col| {
const diff = diffs.isSet(col);
if (std.ascii.isPrint(byte)) {
try self.writeDiff(writer, "{c}", .{byte}, diff);
} else {
if (self.terminal_mode == .windows_api) {
try self.writeDiff(writer, ".", .{}, diff);
continue;
}
// We don't want to do this for all control codes because most control codes apart from
// the ones that Zig has escape sequences for are likely not very useful to print as symbols.
switch (byte) {
'\n' => try self.writeDiff(writer, "␊", .{}, diff),
'\r' => try self.writeDiff(writer, "␍", .{}, diff),
'\t' => try self.writeDiff(writer, "␉", .{}, diff),
else => try self.writeDiff(writer, ".", .{}, diff),
}
}
}
try writer.writeByte('\n');
row += 1;
}
}
fn terminal(self: *const BytesDiffer, writer: *Io.Writer) Io.Terminal {
return .{ .writer = writer, .mode = self.terminal_mode };
}
fn writeDiff(self: BytesDiffer, writer: *Io.Writer, comptime fmt: []const u8, args: anytype, diff: bool) !void {
if (diff) try self.terminal(writer).setColor(.red);
try writer.print(fmt, args);
if (diff) try self.terminal(writer).setColor(.reset);
}
}