| author | |
| committer | |
| log | 3122fd0ba0eb4cdb17616658b462a255a37f1ad7 |
| tree | 2564a986d66fab02726aa405d23df0c645b27db5 |
| parent | 9ca6cc1e2f6af1b5197f92e4b56865ab822f4040 |
| parent | 2b2c9c5db893c7bc0352d1738c1658a5fcd32d62 |
| signature |
Add type-erased writer and GenericWriter6 files changed, 181 insertions(+), 83 deletions(-)
CMakeLists.txt+1-1| ... | ... | @@ -265,7 +265,7 @@ set(ZIG_STAGE2_SOURCES |
| 265 | 265 | "${CMAKE_SOURCE_DIR}/lib/std/io/limited_reader.zig" |
| 266 | 266 | "${CMAKE_SOURCE_DIR}/lib/std/io/Reader.zig" |
| 267 | 267 | "${CMAKE_SOURCE_DIR}/lib/std/io/seekable_stream.zig" |
| 268 | "${CMAKE_SOURCE_DIR}/lib/std/io/writer.zig" | |
| 268 | "${CMAKE_SOURCE_DIR}/lib/std/io/Writer.zig" | |
| 269 | 269 | "${CMAKE_SOURCE_DIR}/lib/std/json.zig" |
| 270 | 270 | "${CMAKE_SOURCE_DIR}/lib/std/json/stringify.zig" |
| 271 | 271 | "${CMAKE_SOURCE_DIR}/lib/std/leb128.zig" |
lib/std/fmt.zig+5-2| ... | ... | @@ -1986,7 +1986,10 @@ pub const BufPrintError = error{ |
| 1986 | 1986 | /// Returns a slice of the bytes printed to. |
| 1987 | 1987 | pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintError![]u8 { |
| 1988 | 1988 | var fbs = std.io.fixedBufferStream(buf); |
| 1989 | try format(fbs.writer(), fmt, args); | |
| 1989 | format(fbs.writer().any(), fmt, args) catch |err| switch (err) { | |
| 1990 | error.NoSpaceLeft => return error.NoSpaceLeft, | |
| 1991 | else => unreachable, | |
| 1992 | }; | |
| 1990 | 1993 | return fbs.getWritten(); |
| 1991 | 1994 | } |
| 1992 | 1995 | |
| ... | ... | @@ -1998,7 +2001,7 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr |
| 1998 | 2001 | /// Count the characters needed for format. Useful for preallocating memory |
| 1999 | 2002 | pub fn count(comptime fmt: []const u8, args: anytype) u64 { |
| 2000 | 2003 | var counting_writer = std.io.countingWriter(std.io.null_writer); |
| 2001 | format(counting_writer.writer(), fmt, args) catch |err| switch (err) {}; | |
| 2004 | format(counting_writer.writer().any(), fmt, args) catch unreachable; | |
| 2002 | 2005 | return counting_writer.bytes_written; |
| 2003 | 2006 | } |
| 2004 | 2007 |
lib/std/io.zig+62-2| ... | ... | @@ -333,13 +333,73 @@ pub fn GenericReader( |
| 333 | 333 | }; |
| 334 | 334 | } |
| 335 | 335 | |
| 336 | pub fn GenericWriter( | |
| 337 | comptime Context: type, | |
| 338 | comptime WriteError: type, | |
| 339 | comptime writeFn: fn (context: Context, bytes: []const u8) WriteError!usize, | |
| 340 | ) type { | |
| 341 | return struct { | |
| 342 | context: Context, | |
| 343 | ||
| 344 | const Self = @This(); | |
| 345 | pub const Error = WriteError; | |
| 346 | ||
| 347 | pub inline fn write(self: Self, bytes: []const u8) Error!usize { | |
| 348 | return writeFn(self.context, bytes); | |
| 349 | } | |
| 350 | ||
| 351 | pub inline fn writeAll(self: Self, bytes: []const u8) Error!void { | |
| 352 | return @errorCast(self.any().writeAll(bytes)); | |
| 353 | } | |
| 354 | ||
| 355 | pub inline fn print(self: Self, comptime format: []const u8, args: anytype) Error!void { | |
| 356 | return @errorCast(self.any().print(format, args)); | |
| 357 | } | |
| 358 | ||
| 359 | pub inline fn writeByte(self: Self, byte: u8) Error!void { | |
| 360 | return @errorCast(self.any().writeByte(byte)); | |
| 361 | } | |
| 362 | ||
| 363 | pub inline fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void { | |
| 364 | return @errorCast(self.any().writeByteNTimes(byte, n)); | |
| 365 | } | |
| 366 | ||
| 367 | pub inline fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) Error!void { | |
| 368 | return @errorCast(self.any().writeBytesNTimes(bytes, n)); | |
| 369 | } | |
| 370 | ||
| 371 | pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { | |
| 372 | return @errorCast(self.any().writeInt(T, value, endian)); | |
| 373 | } | |
| 374 | ||
| 375 | pub inline fn writeStruct(self: Self, value: anytype) Error!void { | |
| 376 | return @errorCast(self.any().writeStruct(value)); | |
| 377 | } | |
| 378 | ||
| 379 | pub inline fn any(self: *const Self) AnyWriter { | |
| 380 | return .{ | |
| 381 | .context = @ptrCast(&self.context), | |
| 382 | .writeFn = typeErasedWriteFn, | |
| 383 | }; | |
| 384 | } | |
| 385 | ||
| 386 | fn typeErasedWriteFn(context: *const anyopaque, bytes: []const u8) anyerror!usize { | |
| 387 | const ptr: *const Context = @alignCast(@ptrCast(context)); | |
| 388 | return writeFn(ptr.*, bytes); | |
| 389 | } | |
| 390 | }; | |
| 391 | } | |
| 392 | ||
| 336 | 393 | /// Deprecated; consider switching to `AnyReader` or use `GenericReader` |
| 337 | 394 | /// to use previous API. |
| 338 | 395 | pub const Reader = GenericReader; |
| 396 | /// Deprecated; consider switching to `AnyWriter` or use `GenericWriter` | |
| 397 | /// to use previous API. | |
| 398 | pub const Writer = GenericWriter; | |
| 339 | 399 | |
| 340 | 400 | pub const AnyReader = @import("io/Reader.zig"); |
| 401 | pub const AnyWriter = @import("io/Writer.zig"); | |
| 341 | 402 | |
| 342 | pub const Writer = @import("io/writer.zig").Writer; | |
| 343 | 403 | pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream; |
| 344 | 404 | |
| 345 | 405 | pub const BufferedWriter = @import("io/buffered_writer.zig").BufferedWriter; |
| ... | ... | @@ -652,6 +712,7 @@ pub fn PollFiles(comptime StreamEnum: type) type { |
| 652 | 712 | |
| 653 | 713 | test { |
| 654 | 714 | _ = AnyReader; |
| 715 | _ = AnyWriter; | |
| 655 | 716 | _ = @import("io/bit_reader.zig"); |
| 656 | 717 | _ = @import("io/bit_writer.zig"); |
| 657 | 718 | _ = @import("io/buffered_atomic_file.zig"); |
| ... | ... | @@ -661,7 +722,6 @@ test { |
| 661 | 722 | _ = @import("io/counting_writer.zig"); |
| 662 | 723 | _ = @import("io/counting_reader.zig"); |
| 663 | 724 | _ = @import("io/fixed_buffer_stream.zig"); |
| 664 | _ = @import("io/writer.zig"); | |
| 665 | 725 | _ = @import("io/peek_stream.zig"); |
| 666 | 726 | _ = @import("io/seekable_stream.zig"); |
| 667 | 727 | _ = @import("io/stream_source.zig"); |
lib/std/io/Writer.zig created+60| ... | ... | @@ -0,0 +1,60 @@ |
| 1 | const std = @import("../std.zig"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | context: *const anyopaque, | |
| 6 | writeFn: *const fn (context: *const anyopaque, bytes: []const u8) anyerror!usize, | |
| 7 | ||
| 8 | const Self = @This(); | |
| 9 | pub const Error = anyerror; | |
| 10 | ||
| 11 | pub fn write(self: Self, bytes: []const u8) anyerror!usize { | |
| 12 | return self.writeFn(self.context, bytes); | |
| 13 | } | |
| 14 | ||
| 15 | pub fn writeAll(self: Self, bytes: []const u8) anyerror!void { | |
| 16 | var index: usize = 0; | |
| 17 | while (index != bytes.len) { | |
| 18 | index += try self.write(bytes[index..]); | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | pub fn print(self: Self, comptime format: []const u8, args: anytype) anyerror!void { | |
| 23 | return std.fmt.format(self, format, args); | |
| 24 | } | |
| 25 | ||
| 26 | pub fn writeByte(self: Self, byte: u8) anyerror!void { | |
| 27 | const array = [1]u8{byte}; | |
| 28 | return self.writeAll(&array); | |
| 29 | } | |
| 30 | ||
| 31 | pub fn writeByteNTimes(self: Self, byte: u8, n: usize) anyerror!void { | |
| 32 | var bytes: [256]u8 = undefined; | |
| 33 | @memset(bytes[0..], byte); | |
| 34 | ||
| 35 | var remaining: usize = n; | |
| 36 | while (remaining > 0) { | |
| 37 | const to_write = @min(remaining, bytes.len); | |
| 38 | try self.writeAll(bytes[0..to_write]); | |
| 39 | remaining -= to_write; | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 | pub fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) anyerror!void { | |
| 44 | var i: usize = 0; | |
| 45 | while (i < n) : (i += 1) { | |
| 46 | try self.writeAll(bytes); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 50 | pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) anyerror!void { | |
| 51 | var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined; | |
| 52 | mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); | |
| 53 | return self.writeAll(&bytes); | |
| 54 | } | |
| 55 | ||
| 56 | pub fn writeStruct(self: Self, value: anytype) anyerror!void { | |
| 57 | // Only extern and packed structs have defined in-memory layout. | |
| 58 | comptime assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto); | |
| 59 | return self.writeAll(mem.asBytes(&value)); | |
| 60 | } |
lib/std/io/writer.zig deleted-67| ... | ... | @@ -1,67 +0,0 @@ |
| 1 | const std = @import("../std.zig"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | pub fn Writer( | |
| 6 | comptime Context: type, | |
| 7 | comptime WriteError: type, | |
| 8 | comptime writeFn: fn (context: Context, bytes: []const u8) WriteError!usize, | |
| 9 | ) type { | |
| 10 | return struct { | |
| 11 | context: Context, | |
| 12 | ||
| 13 | const Self = @This(); | |
| 14 | pub const Error = WriteError; | |
| 15 | ||
| 16 | pub fn write(self: Self, bytes: []const u8) Error!usize { | |
| 17 | return writeFn(self.context, bytes); | |
| 18 | } | |
| 19 | ||
| 20 | pub fn writeAll(self: Self, bytes: []const u8) Error!void { | |
| 21 | var index: usize = 0; | |
| 22 | while (index != bytes.len) { | |
| 23 | index += try self.write(bytes[index..]); | |
| 24 | } | |
| 25 | } | |
| 26 | ||
| 27 | pub fn print(self: Self, comptime format: []const u8, args: anytype) Error!void { | |
| 28 | return std.fmt.format(self, format, args); | |
| 29 | } | |
| 30 | ||
| 31 | pub fn writeByte(self: Self, byte: u8) Error!void { | |
| 32 | const array = [1]u8{byte}; | |
| 33 | return self.writeAll(&array); | |
| 34 | } | |
| 35 | ||
| 36 | pub fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void { | |
| 37 | var bytes: [256]u8 = undefined; | |
| 38 | @memset(bytes[0..], byte); | |
| 39 | ||
| 40 | var remaining: usize = n; | |
| 41 | while (remaining > 0) { | |
| 42 | const to_write = @min(remaining, bytes.len); | |
| 43 | try self.writeAll(bytes[0..to_write]); | |
| 44 | remaining -= to_write; | |
| 45 | } | |
| 46 | } | |
| 47 | ||
| 48 | pub fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) Error!void { | |
| 49 | var i: usize = 0; | |
| 50 | while (i < n) : (i += 1) { | |
| 51 | try self.writeAll(bytes); | |
| 52 | } | |
| 53 | } | |
| 54 | ||
| 55 | pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { | |
| 56 | var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined; | |
| 57 | mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); | |
| 58 | return self.writeAll(&bytes); | |
| 59 | } | |
| 60 | ||
| 61 | pub fn writeStruct(self: Self, value: anytype) Error!void { | |
| 62 | // Only extern and packed structs have defined in-memory layout. | |
| 63 | comptime assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto); | |
| 64 | return self.writeAll(mem.asBytes(&value)); | |
| 65 | } | |
| 66 | }; | |
| 67 | } |
src/codegen/c.zig+53-11| ... | ... | @@ -306,7 +306,7 @@ pub const Function = struct { |
| 306 | 306 | const ty = f.typeOf(ref); |
| 307 | 307 | |
| 308 | 308 | const result: CValue = if (lowersToArray(ty, mod)) result: { |
| 309 | const writer = f.object.code_header.writer(); | |
| 309 | const writer = f.object.codeHeaderWriter(); | |
| 310 | 310 | const alignment: Alignment = .none; |
| 311 | 311 | const decl_c_value = try f.allocLocalValue(ty, alignment); |
| 312 | 312 | const gpa = f.object.dg.gpa; |
| ... | ... | @@ -534,6 +534,10 @@ pub const Object = struct { |
| 534 | 534 | fn writer(o: *Object) IndentWriter(std.ArrayList(u8).Writer).Writer { |
| 535 | 535 | return o.indent_writer.writer(); |
| 536 | 536 | } |
| 537 | ||
| 538 | fn codeHeaderWriter(o: *Object) ArrayListWriter { | |
| 539 | return arrayListWriter(&o.code_header); | |
| 540 | } | |
| 537 | 541 | }; |
| 538 | 542 | |
| 539 | 543 | /// This data is available both when outputting .c code and when outputting an .h file. |
| ... | ... | @@ -557,6 +561,10 @@ pub const DeclGen = struct { |
| 557 | 561 | flush, |
| 558 | 562 | }; |
| 559 | 563 | |
| 564 | fn fwdDeclWriter(dg: *DeclGen) ArrayListWriter { | |
| 565 | return arrayListWriter(&dg.fwd_decl); | |
| 566 | } | |
| 567 | ||
| 560 | 568 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { |
| 561 | 569 | @setCold(true); |
| 562 | 570 | const mod = dg.module; |
| ... | ... | @@ -1982,7 +1990,7 @@ pub const DeclGen = struct { |
| 1982 | 1990 | fwd_kind: enum { tentative, final }, |
| 1983 | 1991 | ) !void { |
| 1984 | 1992 | const decl = dg.module.declPtr(decl_index); |
| 1985 | const fwd = dg.fwd_decl.writer(); | |
| 1993 | const fwd = dg.fwdDeclWriter(); | |
| 1986 | 1994 | const is_global = variable.is_extern or dg.declIsGlobal(.{ .ty = decl.ty, .val = decl.val }); |
| 1987 | 1995 | try fwd.writeAll(if (is_global) "zig_extern " else "static "); |
| 1988 | 1996 | const maybe_exports = dg.module.decl_exports.get(decl_index); |
| ... | ... | @@ -2668,7 +2676,7 @@ fn genExports(o: *Object) !void { |
| 2668 | 2676 | }; |
| 2669 | 2677 | const decl = mod.declPtr(decl_index); |
| 2670 | 2678 | const tv: TypedValue = .{ .ty = decl.ty, .val = Value.fromInterned((try decl.internValue(mod))) }; |
| 2671 | const fwd = o.dg.fwd_decl.writer(); | |
| 2679 | const fwd = o.dg.fwdDeclWriter(); | |
| 2672 | 2680 | |
| 2673 | 2681 | const exports = mod.decl_exports.get(decl_index) orelse return; |
| 2674 | 2682 | if (exports.items.len < 2) return; |
| ... | ... | @@ -2782,7 +2790,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { |
| 2782 | 2790 | const fn_cty = try o.dg.typeToCType(fn_decl.ty, .complete); |
| 2783 | 2791 | const fn_info = fn_cty.cast(CType.Payload.Function).?.data; |
| 2784 | 2792 | |
| 2785 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | |
| 2793 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | |
| 2786 | 2794 | try fwd_decl_writer.print("static zig_{s} ", .{@tagName(key)}); |
| 2787 | 2795 | try o.dg.renderFunctionSignature( |
| 2788 | 2796 | fwd_decl_writer, |
| ... | ... | @@ -2824,7 +2832,7 @@ pub fn genFunc(f: *Function) !void { |
| 2824 | 2832 | defer o.code_header.deinit(); |
| 2825 | 2833 | |
| 2826 | 2834 | const is_global = o.dg.declIsGlobal(tv); |
| 2827 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | |
| 2835 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | |
| 2828 | 2836 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2829 | 2837 | |
| 2830 | 2838 | if (mod.decl_exports.get(decl_index)) |exports| |
| ... | ... | @@ -2879,7 +2887,7 @@ pub fn genFunc(f: *Function) !void { |
| 2879 | 2887 | }; |
| 2880 | 2888 | free_locals.sort(SortContext{ .keys = free_locals.keys() }); |
| 2881 | 2889 | |
| 2882 | const w = o.code_header.writer(); | |
| 2890 | const w = o.codeHeaderWriter(); | |
| 2883 | 2891 | for (free_locals.values()) |list| { |
| 2884 | 2892 | for (list.keys()) |local_index| { |
| 2885 | 2893 | const local = f.locals.items[local_index]; |
| ... | ... | @@ -2907,7 +2915,7 @@ pub fn genDecl(o: *Object) !void { |
| 2907 | 2915 | |
| 2908 | 2916 | if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return; |
| 2909 | 2917 | if (tv.val.getExternFunc(mod)) |_| { |
| 2910 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | |
| 2918 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | |
| 2911 | 2919 | try fwd_decl_writer.writeAll("zig_extern "); |
| 2912 | 2920 | try o.dg.renderFunctionSignature(fwd_decl_writer, decl_index, .forward, .{ .export_index = 0 }); |
| 2913 | 2921 | try fwd_decl_writer.writeAll(";\n"); |
| ... | ... | @@ -2948,7 +2956,7 @@ pub fn genDeclValue( |
| 2948 | 2956 | link_section: InternPool.OptionalNullTerminatedString, |
| 2949 | 2957 | ) !void { |
| 2950 | 2958 | const mod = o.dg.module; |
| 2951 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | |
| 2959 | const fwd_decl_writer = o.dg.fwdDeclWriter(); | |
| 2952 | 2960 | |
| 2953 | 2961 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static "); |
| 2954 | 2962 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, Const, alignment, .complete); |
| ... | ... | @@ -2992,7 +3000,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { |
| 2992 | 3000 | .ty = decl.ty, |
| 2993 | 3001 | .val = decl.val, |
| 2994 | 3002 | }; |
| 2995 | const writer = dg.fwd_decl.writer(); | |
| 3003 | const writer = dg.fwdDeclWriter(); | |
| 2996 | 3004 | |
| 2997 | 3005 | switch (tv.ty.zigTypeTag(mod)) { |
| 2998 | 3006 | .Fn => if (dg.declIsGlobal(tv)) { |
| ... | ... | @@ -7517,11 +7525,25 @@ fn toAtomicRmwSuffix(order: std.builtin.AtomicRmwOp) []const u8 { |
| 7517 | 7525 | }; |
| 7518 | 7526 | } |
| 7519 | 7527 | |
| 7528 | const ArrayListWriter = ErrorOnlyGenericWriter(std.ArrayList(u8).Writer.Error); | |
| 7529 | ||
| 7530 | fn arrayListWriter(list: *std.ArrayList(u8)) ArrayListWriter { | |
| 7531 | return .{ .context = .{ | |
| 7532 | .context = list, | |
| 7533 | .writeFn = struct { | |
| 7534 | fn write(context: *const anyopaque, bytes: []const u8) anyerror!usize { | |
| 7535 | const l: *std.ArrayList(u8) = @alignCast(@constCast(@ptrCast(context))); | |
| 7536 | return l.writer().write(bytes); | |
| 7537 | } | |
| 7538 | }.write, | |
| 7539 | } }; | |
| 7540 | } | |
| 7541 | ||
| 7520 | 7542 | fn IndentWriter(comptime UnderlyingWriter: type) type { |
| 7521 | 7543 | return struct { |
| 7522 | 7544 | const Self = @This(); |
| 7523 | 7545 | pub const Error = UnderlyingWriter.Error; |
| 7524 | pub const Writer = std.io.Writer(*Self, Error, write); | |
| 7546 | pub const Writer = ErrorOnlyGenericWriter(Error); | |
| 7525 | 7547 | |
| 7526 | 7548 | pub const indent_delta = 1; |
| 7527 | 7549 | |
| ... | ... | @@ -7530,7 +7552,10 @@ fn IndentWriter(comptime UnderlyingWriter: type) type { |
| 7530 | 7552 | current_line_empty: bool = true, |
| 7531 | 7553 | |
| 7532 | 7554 | pub fn writer(self: *Self) Writer { |
| 7533 | return .{ .context = self }; | |
| 7555 | return .{ .context = .{ | |
| 7556 | .context = self, | |
| 7557 | .writeFn = writeAny, | |
| 7558 | } }; | |
| 7534 | 7559 | } |
| 7535 | 7560 | |
| 7536 | 7561 | pub fn write(self: *Self, bytes: []const u8) Error!usize { |
| ... | ... | @@ -7545,6 +7570,11 @@ fn IndentWriter(comptime UnderlyingWriter: type) type { |
| 7545 | 7570 | return self.writeNoIndent(bytes); |
| 7546 | 7571 | } |
| 7547 | 7572 | |
| 7573 | fn writeAny(context: *const anyopaque, bytes: []const u8) anyerror!usize { | |
| 7574 | const self: *Self = @alignCast(@constCast(@ptrCast(context))); | |
| 7575 | return self.write(bytes); | |
| 7576 | } | |
| 7577 | ||
| 7548 | 7578 | pub fn insertNewline(self: *Self) Error!void { |
| 7549 | 7579 | _ = try self.writeNoIndent("\n"); |
| 7550 | 7580 | } |
| ... | ... | @@ -7570,6 +7600,18 @@ fn IndentWriter(comptime UnderlyingWriter: type) type { |
| 7570 | 7600 | }; |
| 7571 | 7601 | } |
| 7572 | 7602 | |
| 7603 | /// A wrapper around `std.io.AnyWriter` that maintains a generic error set while | |
| 7604 | /// erasing the rest of the implementation. This is intended to avoid duplicate | |
| 7605 | /// generic instantiations for writer types which share the same error set, while | |
| 7606 | /// maintaining ease of error handling. | |
| 7607 | fn ErrorOnlyGenericWriter(comptime Error: type) type { | |
| 7608 | return std.io.GenericWriter(std.io.AnyWriter, Error, struct { | |
| 7609 | fn write(context: std.io.AnyWriter, bytes: []const u8) Error!usize { | |
| 7610 | return @errorCast(context.write(bytes)); | |
| 7611 | } | |
| 7612 | }.write); | |
| 7613 | } | |
| 7614 | ||
| 7573 | 7615 | fn toCIntBits(zig_bits: u32) ?u32 { |
| 7574 | 7616 | for (&[_]u8{ 8, 16, 32, 64, 128 }) |c_bits| { |
| 7575 | 7617 | if (zig_bits <= c_bits) { |