diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-07-30 19:02:00 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-07-31 22:10:11 -0700 |
| commit | c49c90a42af225f6f125c1bedd0b3cb423de2b4d (patch) | |
| tree | 3aa6bd9bdfe609eb3a38a6f3f944965915979fc6 /src/Package/Fetch/git.zig | |
| parent | 4c04835a08097d18a30ba74ef9a3aa59f3b90fd3 (diff) | |
| download | zig-c49c90a42af225f6f125c1bedd0b3cb423de2b4d.tar.gz zig-c49c90a42af225f6f125c1bedd0b3cb423de2b4d.zip | |
fetch: update API usage
Diffstat (limited to 'src/Package/Fetch/git.zig')
| -rw-r--r-- | src/Package/Fetch/git.zig | 324 |
1 files changed, 141 insertions, 183 deletions
diff --git a/src/Package/Fetch/git.zig b/src/Package/Fetch/git.zig index f2d59f95e8..00e542b2d2 100644 --- a/src/Package/Fetch/git.zig +++ b/src/Package/Fetch/git.zig @@ -66,6 +66,33 @@ pub const Oid = union(Format) { } }; + const Hashing = union(Format) { + sha1: std.Io.Writer.Hashing(Sha1), + sha256: std.Io.Writer.Hashing(Sha256), + + fn init(oid_format: Format, buffer: []u8) Hashing { + return switch (oid_format) { + .sha1 => .{ .sha1 = .init(buffer) }, + .sha256 => .{ .sha256 = .init(buffer) }, + }; + } + + fn writer(h: *@This()) *std.Io.Writer { + return switch (h.*) { + inline else => |*inner| &inner.writer, + }; + } + + fn final(h: *@This()) Oid { + switch (h.*) { + inline else => |*inner, tag| { + inner.writer.flush() catch unreachable; // hashers cannot fail + return @unionInit(Oid, @tagName(tag), inner.hasher.finalResult()); + }, + } + } + }; + pub fn fromBytes(oid_format: Format, bytes: []const u8) Oid { assert(bytes.len == oid_format.byteLength()); return switch (oid_format) { @@ -73,9 +100,9 @@ pub const Oid = union(Format) { }; } - pub fn readBytes(oid_format: Format, reader: anytype) !Oid { + pub fn readBytes(oid_format: Format, reader: *std.Io.Reader) !Oid { return switch (oid_format) { - inline else => |tag| @unionInit(Oid, @tagName(tag), try reader.readBytesNoEof(tag.byteLength())), + inline else => |tag| @unionInit(Oid, @tagName(tag), (try reader.takeArray(tag.byteLength())).*), }; } @@ -166,8 +193,15 @@ pub const Diagnostics = struct { pub const Repository = struct { odb: Odb, - pub fn init(allocator: Allocator, format: Oid.Format, pack_file: *std.fs.File.Reader, index_file: std.fs.File) !Repository { - return .{ .odb = try Odb.init(allocator, format, pack_file, index_file) }; + pub fn init( + repo: *Repository, + allocator: Allocator, + format: Oid.Format, + pack_file: *std.fs.File.Reader, + index_file: *std.fs.File.Reader, + ) !void { + repo.* = .{ .odb = undefined }; + try repo.odb.init(allocator, format, pack_file, index_file); } pub fn deinit(repository: *Repository) void { @@ -337,22 +371,28 @@ const Odb = struct { format: Oid.Format, pack_file: *std.fs.File.Reader, index_header: IndexHeader, - index_file: std.fs.File, + index_file: *std.fs.File.Reader, cache: ObjectCache = .{}, allocator: Allocator, /// Initializes the database from open pack and index files. - fn init(allocator: Allocator, format: Oid.Format, pack_file: *std.fs.File.Reader, index_file: std.fs.File) !Odb { + fn init( + odb: *Odb, + allocator: Allocator, + format: Oid.Format, + pack_file: *std.fs.File.Reader, + index_file: *std.fs.File.Reader, + ) !void { try pack_file.seekTo(0); try index_file.seekTo(0); - const index_header = try IndexHeader.read(index_file.deprecatedReader()); - return .{ + odb.* = .{ .format = format, .pack_file = pack_file, - .index_header = index_header, + .index_header = undefined, .index_file = index_file, .allocator = allocator, }; + try odb.index_header.read(&index_file.interface); } fn deinit(odb: *Odb) void { @@ -369,7 +409,7 @@ const Odb = struct { const base_object = while (true) { if (odb.cache.get(base_offset)) |base_object| break base_object; - base_header = try EntryHeader.read(odb.format, odb.pack_file.interface.adaptToOldInterface()); + base_header = try EntryHeader.read(odb.format, &odb.pack_file.interface); switch (base_header) { .ofs_delta => |ofs_delta| { try delta_offsets.append(odb.allocator, base_offset); @@ -412,7 +452,7 @@ const Odb = struct { const found_index = while (start_index < end_index) { const mid_index = start_index + (end_index - start_index) / 2; try odb.index_file.seekTo(IndexHeader.size + mid_index * oid_length); - const mid_oid = try Oid.readBytes(odb.format, odb.index_file.deprecatedReader()); + const mid_oid = try Oid.readBytes(odb.format, &odb.index_file.interface); switch (mem.order(u8, mid_oid.slice(), oid.slice())) { .lt => start_index = mid_index + 1, .gt => end_index = mid_index, @@ -423,12 +463,12 @@ const Odb = struct { const n_objects = odb.index_header.fan_out_table[255]; const offset_values_start = IndexHeader.size + n_objects * (oid_length + 4); try odb.index_file.seekTo(offset_values_start + found_index * 4); - const l1_offset: packed struct { value: u31, big: bool } = @bitCast(try odb.index_file.deprecatedReader().readInt(u32, .big)); + const l1_offset: packed struct { value: u31, big: bool } = @bitCast(try odb.index_file.interface.takeInt(u32, .big)); const pack_offset = pack_offset: { if (l1_offset.big) { const l2_offset_values_start = offset_values_start + n_objects * 4; try odb.index_file.seekTo(l2_offset_values_start + l1_offset.value * 4); - break :pack_offset try odb.index_file.deprecatedReader().readInt(u64, .big); + break :pack_offset try odb.index_file.interface.takeInt(u64, .big); } else { break :pack_offset l1_offset.value; } @@ -1080,18 +1120,18 @@ const PackHeader = struct { const signature = "PACK"; const supported_version = 2; - fn read(reader: anytype) !PackHeader { - const actual_signature = reader.readBytesNoEof(4) catch |e| switch (e) { + fn read(reader: *std.Io.Reader) !PackHeader { + const actual_signature = reader.take(4) catch |e| switch (e) { error.EndOfStream => return error.InvalidHeader, else => |other| return other, }; - if (!mem.eql(u8, &actual_signature, signature)) return error.InvalidHeader; - const version = reader.readInt(u32, .big) catch |e| switch (e) { + if (!mem.eql(u8, actual_signature, signature)) return error.InvalidHeader; + const version = reader.takeInt(u32, .big) catch |e| switch (e) { error.EndOfStream => return error.InvalidHeader, else => |other| return other, }; if (version != supported_version) return error.UnsupportedVersion; - const total_objects = reader.readInt(u32, .big) catch |e| switch (e) { + const total_objects = reader.takeInt(u32, .big) catch |e| switch (e) { error.EndOfStream => return error.InvalidHeader, else => |other| return other, }; @@ -1143,13 +1183,13 @@ const EntryHeader = union(Type) { }; } - fn read(format: Oid.Format, reader: anytype) !EntryHeader { + fn read(format: Oid.Format, reader: *std.Io.Reader) !EntryHeader { const InitialByte = packed struct { len: u4, type: u3, has_next: bool }; - const initial: InitialByte = @bitCast(reader.readByte() catch |e| switch (e) { + const initial: InitialByte = @bitCast(reader.takeByte() catch |e| switch (e) { error.EndOfStream => return error.InvalidFormat, else => |other| return other, }); - const rest_len = if (initial.has_next) try readSizeVarInt(reader) else 0; + const rest_len = if (initial.has_next) try reader.takeLeb128(u64) else 0; var uncompressed_length: u64 = initial.len; uncompressed_length |= std.math.shlExact(u64, rest_len, 4) catch return error.InvalidFormat; const @"type" = std.enums.fromInt(EntryHeader.Type, initial.type) orelse return error.InvalidFormat; @@ -1172,25 +1212,12 @@ const EntryHeader = union(Type) { } }; -fn readSizeVarInt(r: anytype) !u64 { - const Byte = packed struct { value: u7, has_next: bool }; - var b: Byte = @bitCast(try r.readByte()); - var value: u64 = b.value; - var shift: u6 = 0; - while (b.has_next) { - b = @bitCast(try r.readByte()); - shift = std.math.add(u6, shift, 7) catch return error.InvalidFormat; - value |= @as(u64, b.value) << shift; - } - return value; -} - -fn readOffsetVarInt(r: anytype) !u64 { +fn readOffsetVarInt(r: *std.Io.Reader) !u64 { const Byte = packed struct { value: u7, has_next: bool }; - var b: Byte = @bitCast(try r.readByte()); + var b: Byte = @bitCast(try r.takeByte()); var value: u64 = b.value; while (b.has_next) { - b = @bitCast(try r.readByte()); + b = @bitCast(try r.takeByte()); value = std.math.shlExact(u64, value + 1, 7) catch return error.InvalidFormat; value |= b.value; } @@ -1204,19 +1231,12 @@ const IndexHeader = struct { const supported_version = 2; const size = 4 + 4 + @sizeOf([256]u32); - fn read(reader: anytype) !IndexHeader { - var header_bytes = try reader.readBytesNoEof(size); - if (!mem.eql(u8, header_bytes[0..4], signature)) return error.InvalidHeader; - const version = mem.readInt(u32, header_bytes[4..8], .big); + fn read(index_header: *IndexHeader, reader: *std.Io.Reader) !void { + const sig = try reader.take(4); + if (!mem.eql(u8, sig, signature)) return error.InvalidHeader; + const version = try reader.takeInt(u32, .big); if (version != supported_version) return error.UnsupportedVersion; - - var fan_out_table: [256]u32 = undefined; - var fan_out_table_stream = std.io.fixedBufferStream(header_bytes[8..]); - const fan_out_table_reader = fan_out_table_stream.reader(); - for (&fan_out_table) |*entry| { - entry.* = fan_out_table_reader.readInt(u32, .big) catch unreachable; - } - return .{ .fan_out_table = fan_out_table }; + try reader.readSliceEndian(u32, &index_header.fan_out_table, .big); } }; @@ -1227,7 +1247,12 @@ const IndexEntry = struct { /// Writes out a version 2 index for the given packfile, as documented in /// [pack-format](https://git-scm.com/docs/pack-format). -pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: *std.fs.File.Reader, index_writer: anytype) !void { +pub fn indexPack( + allocator: Allocator, + format: Oid.Format, + pack: *std.fs.File.Reader, + index_writer: *std.fs.File.Writer, +) !void { try pack.seekTo(0); var index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry) = .empty; @@ -1280,8 +1305,8 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: *std.fs.File.Re } @memset(fan_out_table[fan_out_index..], count); - var index_hashed_writer = hashedWriter(index_writer, Oid.Hasher.init(format)); - const writer = index_hashed_writer.writer(); + var index_hashed_writer = std.Io.Writer.hashed(&index_writer.interface, Oid.Hasher.init(format), &.{}); + const writer = &index_hashed_writer.writer; try writer.writeAll(IndexHeader.signature); try writer.writeInt(u32, IndexHeader.supported_version, .big); for (fan_out_table) |fan_out_entry| { @@ -1314,7 +1339,8 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: *std.fs.File.Re try writer.writeAll(pack_checksum.slice()); const index_checksum = index_hashed_writer.hasher.finalResult(); - try index_writer.writeAll(index_checksum.slice()); + try index_writer.interface.writeAll(index_checksum.slice()); + try index_writer.end(); } /// Performs the first pass over the packfile data for index construction. @@ -1328,65 +1354,51 @@ fn indexPackFirstPass( index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry), pending_deltas: *std.ArrayListUnmanaged(IndexEntry), ) !Oid { - var pack_counting_reader = std.io.countingReader(pack.interface.adaptToOldInterface()); - var pack_hashed_reader = hashedReader(pack_counting_reader.reader(), Oid.Hasher.init(format)); - const pack_reader = pack_hashed_reader.reader(); - - const pack_header = try PackHeader.read(pack_reader); - - var current_entry: u32 = 0; - while (current_entry < pack_header.total_objects) : (current_entry += 1) { - const entry_offset = pack_counting_reader.bytes_read; - var entry_crc32_reader = hashedReader(pack_reader, std.hash.Crc32.init()); - const entry_header = try EntryHeader.read(format, entry_crc32_reader.reader()); - var adapter_buffer: [1024]u8 = undefined; - var adapter = entry_crc32_reader.reader().adaptToNewApi(&adapter_buffer); - var flate_buffer: [std.compress.flate.max_window_len]u8 = undefined; - var entry_decompress_stream: std.compress.flate.Decompress = .init(&adapter.new_interface, .zlib, &flate_buffer); - const old = entry_decompress_stream.reader.adaptToOldInterface(); - var entry_counting_reader = std.io.countingReader(old); + var flate_buffer: [std.compress.flate.max_window_len]u8 = undefined; + var entry_buffer: [1024]u8 = undefined; // Input buffer to flate. + var pack_buffer: [2048]u8 = undefined; // Reasonably large buffer for file system. + var hasher_buffer: [64]u8 = undefined; + var pack_hashed = pack.interface.hashed(Oid.Hasher.init(format), &pack_buffer); + + const pack_header = try PackHeader.read(&pack_hashed.reader); + + for (0..pack_header.total_objects) |_| { + const entry_offset = pack.logicalPos(); + var entry_crc32_stream = pack_hashed.reader.hashed(std.hash.Crc32.init(), &entry_buffer); + const entry_header = try EntryHeader.read(format, &entry_crc32_stream.reader); + var entry_decompress: std.compress.flate.Decompress = .init(&entry_crc32_stream.reader, .zlib, &flate_buffer); switch (entry_header) { .commit, .tree, .blob, .tag => |object| { - var entry_hashed_writer = hashedWriter(std.io.null_writer, Oid.Hasher.init(format)); - const entry_writer = entry_hashed_writer.writer(); + var oid_hasher: Oid.Hashing = .init(format, &hasher_buffer); + const oid_hasher_w = oid_hasher.writer(); // The object header is not included in the pack data but is // part of the object's ID - try entry_writer.print("{s} {d}\x00", .{ @tagName(entry_header), object.uncompressed_length }); - var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); - try fifo.pump(entry_counting_reader.reader(), entry_writer); - if (entry_counting_reader.bytes_read != object.uncompressed_length) { - return error.InvalidObject; - } - const oid = entry_hashed_writer.hasher.finalResult(); + try oid_hasher_w.print("{t} {d}\x00", .{ entry_header, object.uncompressed_length }); + const n = try entry_decompress.reader.streamRemaining(oid_hasher_w); + if (n != object.uncompressed_length) return error.InvalidObject; + const oid = oid_hasher.final(); try index_entries.put(allocator, oid, .{ .offset = entry_offset, - .crc32 = entry_crc32_reader.hasher.final(), + .crc32 = entry_crc32_stream.hasher.final(), }); }, inline .ofs_delta, .ref_delta => |delta| { - var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); - try fifo.pump(entry_counting_reader.reader(), std.io.null_writer); - if (entry_counting_reader.bytes_read != delta.uncompressed_length) { - return error.InvalidObject; - } + const n = try entry_decompress.reader.discardRemaining(); + if (n != delta.uncompressed_length) return error.InvalidObject; try pending_deltas.append(allocator, .{ .offset = entry_offset, - .crc32 = entry_crc32_reader.hasher.final(), + .crc32 = entry_crc32_stream.hasher.final(), }); }, } } - const pack_checksum = pack_hashed_reader.hasher.finalResult(); - const recorded_checksum = try Oid.readBytes(format, pack.interface.adaptToOldInterface()); + const pack_checksum = pack_hashed.hasher.finalResult(); + const recorded_checksum = try Oid.readBytes(format, &pack.interface); if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) { return error.CorruptedPack; } - _ = pack_reader.readByte() catch |e| switch (e) { - error.EndOfStream => return pack_checksum, - else => |other| return other, - }; - return error.InvalidFormat; + return pack_checksum; } /// Attempts to determine the final object ID of the given deltified object. @@ -1409,7 +1421,7 @@ fn indexPackHashDelta( if (cache.get(base_offset)) |base_object| break base_object; try pack.seekTo(base_offset); - base_header = try EntryHeader.read(format, pack.interface.adaptToOldInterface()); + base_header = try EntryHeader.read(format, &pack.interface); switch (base_header) { .ofs_delta => |ofs_delta| { try delta_offsets.append(allocator, base_offset); @@ -1431,11 +1443,13 @@ fn indexPackHashDelta( const base_data = try resolveDeltaChain(allocator, format, pack, base_object, delta_offsets.items, cache); - var entry_hasher: Oid.Hasher = .init(format); - var entry_hashed_writer = hashedWriter(std.io.null_writer, &entry_hasher); - try entry_hashed_writer.writer().print("{s} {}\x00", .{ @tagName(base_object.type), base_data.len }); - entry_hasher.update(base_data); - return entry_hasher.finalResult(); + var entry_hasher_buffer: [64]u8 = undefined; + var entry_hasher: Oid.Hashing = .init(format, &entry_hasher_buffer); + const entry_hasher_w = entry_hasher.writer(); + // Writes to hashers cannot fail. + entry_hasher_w.print("{t} {d}\x00", .{ base_object.type, base_data.len }) catch unreachable; + entry_hasher_w.writeAll(base_data) catch unreachable; + return entry_hasher.final(); } /// Resolves a chain of deltas, returning the final base object data. `pack` is @@ -1457,21 +1471,19 @@ fn resolveDeltaChain( const delta_offset = delta_offsets[i]; try pack.seekTo(delta_offset); - const delta_header = try EntryHeader.read(format, pack.interface.adaptToOldInterface()); + const delta_header = try EntryHeader.read(format, &pack.interface); const delta_data = try readObjectRaw(allocator, &pack.interface, delta_header.uncompressedLength()); defer allocator.free(delta_data); - var delta_stream = std.io.fixedBufferStream(delta_data); - const delta_reader = delta_stream.reader(); - _ = try readSizeVarInt(delta_reader); // base object size - const expanded_size = try readSizeVarInt(delta_reader); + var delta_reader: std.Io.Reader = .fixed(delta_data); + _ = try delta_reader.takeLeb128(u64); // base object size + const expanded_size = try delta_reader.takeLeb128(u64); const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge; const expanded_data = try allocator.alloc(u8, expanded_alloc_size); errdefer allocator.free(expanded_data); - var expanded_delta_stream = std.io.fixedBufferStream(expanded_data); - var base_stream = std.io.fixedBufferStream(base_data); - try expandDelta(&base_stream, delta_reader, expanded_delta_stream.writer()); - if (expanded_delta_stream.pos != expanded_size) return error.InvalidObject; + var expanded_delta_stream: std.Io.Writer = .fixed(expanded_data); + try expandDelta(base_data, &delta_reader, &expanded_delta_stream); + if (expanded_delta_stream.end != expanded_size) return error.InvalidObject; try cache.put(allocator, delta_offset, .{ .type = base_object.type, .data = expanded_data }); base_data = expanded_data; @@ -1497,9 +1509,10 @@ fn readObjectRaw(allocator: Allocator, reader: *std.Io.Reader, size: u64) ![]u8 /// /// The format of the delta data is documented in /// [pack-format](https://git-scm.com/docs/pack-format). -fn expandDelta(base_object: anytype, delta_reader: anytype, writer: anytype) !void { +fn expandDelta(base_object: []const u8, delta_reader: *std.Io.Reader, writer: *std.Io.Writer) !void { + var base_offset: u32 = 0; while (true) { - const inst: packed struct { value: u7, copy: bool } = @bitCast(delta_reader.readByte() catch |e| switch (e) { + const inst: packed struct { value: u7, copy: bool } = @bitCast(delta_reader.takeByte() catch |e| switch (e) { error.EndOfStream => return, else => |other| return other, }); @@ -1514,27 +1527,23 @@ fn expandDelta(base_object: anytype, delta_reader: anytype, writer: anytype) !vo size3: bool, } = @bitCast(inst.value); const offset_parts: packed struct { offset1: u8, offset2: u8, offset3: u8, offset4: u8 } = .{ - .offset1 = if (available.offset1) try delta_reader.readByte() else 0, - .offset2 = if (available.offset2) try delta_reader.readByte() else 0, - .offset3 = if (available.offset3) try delta_reader.readByte() else 0, - .offset4 = if (available.offset4) try delta_reader.readByte() else 0, + .offset1 = if (available.offset1) try delta_reader.takeByte() else 0, + .offset2 = if (available.offset2) try delta_reader.takeByte() else 0, + .offset3 = if (available.offset3) try delta_reader.takeByte() else 0, + .offset4 = if (available.offset4) try delta_reader.takeByte() else 0, }; - const offset: u32 = @bitCast(offset_parts); + base_offset = @bitCast(offset_parts); const size_parts: packed struct { size1: u8, size2: u8, size3: u8 } = .{ - .size1 = if (available.size1) try delta_reader.readByte() else 0, - .size2 = if (available.size2) try delta_reader.readByte() else 0, - .size3 = if (available.size3) try delta_reader.readByte() else 0, + .size1 = if (available.size1) try delta_reader.takeByte() else 0, + .size2 = if (available.size2) try delta_reader.takeByte() else 0, + .size3 = if (available.size3) try delta_reader.takeByte() else 0, }; var size: u24 = @bitCast(size_parts); if (size == 0) size = 0x10000; - try base_object.seekTo(offset); - var copy_reader = std.io.limitedReader(base_object.reader(), size); - var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); - try fifo.pump(copy_reader.reader(), writer); + try writer.writeAll(base_object[base_offset..][0..size]); + base_offset += size; } else if (inst.value != 0) { - var data_reader = std.io.limitedReader(delta_reader, inst.value); - var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); - try fifo.pump(data_reader.reader(), writer); + try delta_reader.streamExact(writer, inst.value); } else { return error.InvalidDeltaInstruction; } @@ -1564,12 +1573,14 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void defer pack_file.close(); try pack_file.writeAll(testrepo_pack); - var pack_file_buffer: [4096]u8 = undefined; + var pack_file_buffer: [2000]u8 = undefined; var pack_file_reader = pack_file.reader(&pack_file_buffer); var index_file = try git_dir.dir.createFile("testrepo.idx", .{ .read = true }); defer index_file.close(); - try indexPack(testing.allocator, format, &pack_file_reader, index_file.deprecatedWriter()); + var index_file_buffer: [2000]u8 = undefined; + var index_file_writer = index_file.writer(&index_file_buffer); + try indexPack(testing.allocator, format, &pack_file_reader, &index_file_writer); // Arbitrary size limit on files read while checking the repository contents // (all files in the test repo are known to be smaller than this) @@ -1583,7 +1594,9 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void const testrepo_idx = @embedFile("git/testdata/testrepo-" ++ @tagName(format) ++ ".idx"); try testing.expectEqualSlices(u8, testrepo_idx, index_file_data); - var repository = try Repository.init(testing.allocator, format, &pack_file_reader, index_file); + var index_file_reader = index_file.reader(&index_file_buffer); + var repository: Repository = undefined; + try repository.init(testing.allocator, format, &pack_file_reader, &index_file_reader); defer repository.deinit(); var worktree = testing.tmpDir(.{ .iterate = true }); @@ -1704,58 +1717,3 @@ pub fn main() !void { std.debug.print("Diagnostic: {}\n", .{err}); } } - -/// Deprecated -fn hashedReader(reader: anytype, hasher: anytype) HashedReader(@TypeOf(reader), @TypeOf(hasher)) { - return .{ .child_reader = reader, .hasher = hasher }; -} - -/// Deprecated -fn HashedReader(ReaderType: type, HasherType: type) type { - return struct { - child_reader: ReaderType, - hasher: HasherType, - - pub const Error = ReaderType.Error; - pub const Reader = std.io.GenericReader(*@This(), Error, read); - - pub fn read(self: *@This(), buf: []u8) Error!usize { - const amt = try self.child_reader.read(buf); - self.hasher.update(buf[0..amt]); - return amt; - } - - pub fn reader(self: *@This()) Reader { - return .{ .context = self }; - } - }; -} - -/// Deprecated -pub fn HashedWriter(WriterType: type, HasherType: type) type { - return struct { - child_writer: WriterType, - hasher: HasherType, - - pub const Error = WriterType.Error; - pub const Writer = std.io.GenericWriter(*@This(), Error, write); - - pub fn write(self: *@This(), buf: []const u8) Error!usize { - const amt = try self.child_writer.write(buf); - self.hasher.update(buf[0..amt]); - return amt; - } - - pub fn writer(self: *@This()) Writer { - return .{ .context = self }; - } - }; -} - -/// Deprecated -pub fn hashedWriter( - writer: anytype, - hasher: anytype, -) HashedWriter(@TypeOf(writer), @TypeOf(hasher)) { - return .{ .child_writer = writer, .hasher = hasher }; -} |
