Skip to content

Commit 3e8b3e2

Browse files
feat: use anywriter
1 parent ebcc78c commit 3e8b3e2

File tree

3 files changed

+23
-34
lines changed

3 files changed

+23
-34
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ Any+ is a Zig library for handling anytypes in the runtime.
55
## Features
66

77
- [x] Runtime `anytype`
8-
- [ ] Any-reader
98
- [x] Any-writer

any+/anytype.zig

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
const std = @import("std");
22
const Self = @This();
3+
const Anywriter = @import("anywriter.zig");
34

45
// TODO: use any-writer when it exists
5-
const PointerFormat = *const fn (*const Self, options: std.fmt.FormatOptions, *std.io.FixedBufferStream([]u8)) error{ NoSpaceLeft, InvalidCast }!void;
6+
const PointerFormat = *const fn (*const Self, options: std.fmt.FormatOptions, Anywriter.Writer) anyerror!void;
67

78
type: []const u8,
89
size: usize = 0,
@@ -18,9 +19,9 @@ pub inline fn init(value: anytype) Self {
1819
pub inline fn initExplicit(comptime T: type, value: T) Self {
1920
var size: usize = @sizeOf(T);
2021
var ptrFormat: PointerFormat = (struct {
21-
fn func(t: *const Self, options: std.fmt.FormatOptions, stream: *std.io.FixedBufferStream([]u8)) !void {
22+
fn func(t: *const Self, options: std.fmt.FormatOptions, writer: Anywriter.Writer) !void {
2223
const self: T = t.cast(T) catch return error.NoSpaceLeft;
23-
return std.fmt.formatType(self, "", options, stream.writer(), 3);
24+
return std.fmt.formatType(self, "", options, writer, 3);
2425
}
2526
}).func;
2627

@@ -30,9 +31,9 @@ pub inline fn initExplicit(comptime T: type, value: T) Self {
3031
.Enum => @ptrFromInt(@intFromEnum(value)),
3132
.Struct, .Union => blk: {
3233
ptrFormat = (struct {
33-
fn func(t: *const Self, options: std.fmt.FormatOptions, stream: *std.io.FixedBufferStream([]u8)) !void {
34+
fn func(t: *const Self, options: std.fmt.FormatOptions, writer: Anywriter.Writer) !void {
3435
const self: T = t.cast(T) catch return error.NoSpaceLeft;
35-
return if (@hasDecl(T, "format")) self.format("", options, stream.writer()) else std.fmt.formatType(self, "", options, stream.writer(), 3);
36+
return if (@hasDecl(T, "format")) self.format("", options, writer) else std.fmt.formatType(self, "", options, writer, 3);
3637
}
3738
}).func;
3839
break :blk @constCast(&value);
@@ -90,25 +91,8 @@ pub inline fn len(self: Self, comptime T: type) usize {
9091
return @divExact(self.size, size);
9192
}
9293

93-
pub inline fn format(self: *const Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
94-
const size = comptime if (std.mem.indexOf(u8, fmt, "%")) |sizeStart| std.fmt.parseInt(comptime_int, fmt[sizeStart..]) else 0x1000;
95-
96-
const trunc_msg = "(msg truncated)";
97-
var buf: [size + trunc_msg.len]u8 = undefined;
98-
@memset(&buf, 0);
99-
100-
var stream = std.io.fixedBufferStream(buf[0..size]);
101-
const result = self.ptrFormat(self, options, &stream);
102-
103-
if (result == error.NoSpaceLeft) {
104-
@memcpy(buf[size..], trunc_msg);
105-
try writer.writeAll(&buf);
106-
} else if (result == error.InvalidCast) {
107-
std.debug.panic("Failed to cast {s}", .{self.type});
108-
} else {
109-
const end = std.mem.indexOf(u8, &buf, &[_]u8{0}) orelse buf.len;
110-
try writer.writeAll(buf[0..end]);
111-
}
94+
pub inline fn format(self: *const Self, comptime _: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
95+
return self.ptrFormat(self, options, Anywriter.init(writer).writer()) catch |err| std.debug.panic("Anywriter failed: {s}", .{@errorName(err)});
11296
}
11397

11498
test "Casting integers and floats" {

any+/anywriter.zig

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@ const std = @import("std");
22
const Self = @This();
33

44
pub const Error = anyerror;
5-
const PointerWrite = *const fn (*const Self, []const u8) Error!void;
5+
const PointerWrite = *const fn (*const Self, []const u8) Error!usize;
66

7-
pub const Writer = std.io.Writer(Self, Error, write);
7+
pub const Writer = std.io.Writer(*const Self, Error, write);
88

99
type: []const u8,
1010
ptr: *anyopaque,
1111
ptrWrite: PointerWrite,
1212

13-
pub inline fn init(writer: anytype) Self {
14-
return initExplicit(@TypeOf(writer), writer);
13+
pub inline fn init(value: anytype) Self {
14+
return initExplicit(@TypeOf(value), value);
1515
}
1616

17-
pub inline fn initExplicit(comptime T: type, writer: T) Self {
17+
pub inline fn initExplicit(comptime T: type, value: T) Self {
1818
return .{
1919
.type = @typeName(T),
20-
.ptr = @constCast(&writer),
20+
.ptr = @constCast(&value),
2121
.ptrWrite = (struct {
22-
fn func(self: *const Self, buf: []const u8) Error!void {
22+
fn func(self: *const Self, buf: []const u8) Error!usize {
2323
if (!std.mem.eql(u8, self.type, @typeName(T))) return error.InvalidCast;
2424
const w: *T = @ptrCast(@alignCast(self.ptr));
2525
return w.write(buf);
@@ -28,6 +28,12 @@ pub inline fn initExplicit(comptime T: type, writer: T) Self {
2828
};
2929
}
3030

31-
pub fn write(self: Self, buf: []const u8) Error!void {
32-
return self.ptrWrite(&self, buf);
31+
pub fn write(self: *const Self, buf: []const u8) Error!usize {
32+
return self.ptrWrite(self, buf);
33+
}
34+
35+
pub fn writer(self: *const Self) Writer {
36+
return .{
37+
.context = self,
38+
};
3339
}

0 commit comments

Comments
 (0)