std.fmt.format: comptime output parameter

This commit is contained in:
Andrew Kelley 2020-02-05 16:52:18 -05:00
parent 378d733439
commit 84323504ac
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
4 changed files with 38 additions and 45 deletions

View File

@ -78,7 +78,7 @@ fn peekIsAlign(comptime fmt: []const u8) bool {
pub fn format(
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
comptime fmt: []const u8,
args: var,
) Errors!void {
@ -326,7 +326,7 @@ pub fn formatType(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
max_depth: usize,
) Errors!void {
if (comptime std.mem.eql(u8, fmt, "*")) {
@ -488,7 +488,7 @@ fn formatValue(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
if (comptime std.mem.eql(u8, fmt, "B")) {
return formatBytes(value, options, 1000, context, Errors, output);
@ -510,7 +510,7 @@ pub fn formatIntValue(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
comptime var radix = 10;
comptime var uppercase = false;
@ -552,7 +552,7 @@ fn formatFloatValue(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "e")) {
return formatFloatScientific(value, options, context, Errors, output);
@ -569,7 +569,7 @@ pub fn formatText(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
if (fmt.len == 0) {
return output(context, bytes);
@ -590,7 +590,7 @@ pub fn formatAsciiChar(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
return output(context, @as(*const [1]u8, &c)[0..]);
}
@ -600,7 +600,7 @@ pub fn formatBuf(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
try output(context, buf);
@ -620,7 +620,7 @@ pub fn formatFloatScientific(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
var x = @floatCast(f64, value);
@ -715,7 +715,7 @@ pub fn formatFloatDecimal(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
var x = @as(f64, value);
@ -861,7 +861,7 @@ pub fn formatBytes(
comptime radix: usize,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
if (value == 0) {
return output(context, "0B");
@ -902,7 +902,7 @@ pub fn formatInt(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
const int_value = if (@TypeOf(value) == comptime_int) blk: {
const Int = math.IntFittingRange(value, value);
@ -924,7 +924,7 @@ fn formatIntSigned(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
const new_options = FormatOptions{
.width = if (options.width) |w| (if (w == 0) 0 else w - 1) else null,
@ -955,7 +955,7 @@ fn formatIntUnsigned(
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
assert(base >= 2);
var buf: [math.max(@TypeOf(value).bit_count, 1)]u8 = undefined;
@ -1419,7 +1419,7 @@ test "custom" {
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) {
return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", .{ self.x, self.y });
@ -1626,7 +1626,7 @@ test "formatType max_depth" {
options: FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) Errors!void {
if (fmt.len == 0) {
return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", .{ self.x, self.y });

View File

@ -36,7 +36,7 @@ pub fn OutStream(comptime WriteError: type) type {
}
pub fn print(self: *Self, comptime format: []const u8, args: var) Error!void {
return std.fmt.format(self, Error, self.writeFn, format, args);
return std.fmt.format(self, Error, write, format, args);
}
pub fn writeByte(self: *Self, byte: u8) Error!void {

View File

@ -271,7 +271,7 @@ pub const Address = extern union {
options: std.fmt.FormatOptions,
context: var,
comptime Errors: type,
output: fn (@TypeOf(context), []const u8) Errors!void,
comptime output: fn (@TypeOf(context), []const u8) Errors!void,
) !void {
switch (self.any.family) {
os.AF_INET => {
@ -361,7 +361,7 @@ pub const Address = extern union {
};
pub fn connectUnixSocket(path: []const u8) !fs.File {
const opt_non_block = if (std.io.mode == .evented) os.SOCK_NONBLOCK else 0;
const opt_non_block = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
const sockfd = try os.socket(
os.AF_UNIX,
os.SOCK_STREAM | os.SOCK_CLOEXEC | opt_non_block,
@ -377,7 +377,10 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
addr.getOsSockLen(),
);
return fs.File.openHandle(sockfd);
return fs.File{
.handle = socket,
.is_blocking = std.io.mode,
};
}
pub const AddressList = struct {
@ -412,7 +415,7 @@ pub fn tcpConnectToAddress(address: Address) !fs.File {
errdefer os.close(sockfd);
try os.connect(sockfd, &address.any, address.getOsSockLen());
return fs.File{ .handle = sockfd };
return fs.File{ .handle = sockfd, .io_mode = std.io.mode };
}
/// Call `AddressList.deinit` on the result.
@ -1379,7 +1382,10 @@ pub const StreamServer = struct {
var adr_len: os.socklen_t = @sizeOf(Address);
if (os.accept4(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| {
return Connection{
.file = fs.File.openHandle(fd),
.file = fs.File{
.handle = fd,
.io_mode = std.io.mode,
},
.address = accepted_addr,
};
} else |err| switch (err) {

View File

@ -998,7 +998,8 @@ fn printCharValues(out: var, bytes: []const u8) !void {
fn printUnderstandableChar(out: var, char: u8) !void {
if (!std.ascii.isPrint(char) or char == ' ') {
std.fmt.format(out.context, anyerror, out.output, "\\x{X:2}", .{char}) catch {};
const output = @typeInfo(@TypeOf(out)).Pointer.child.output;
std.fmt.format(out.context, anyerror, output, "\\x{X:2}", .{char}) catch {};
} else {
try out.write("'");
try out.write(&[_]u8{printable_char_tab[char]});
@ -1021,34 +1022,20 @@ comptime {
// output: must be a function that takes a `self` idiom parameter
// and a bytes parameter
// context: must be that self
fn makeOutput(output: var, context: var) Output(@TypeOf(output)) {
return Output(@TypeOf(output)){
.output = output,
fn makeOutput(comptime output: var, context: var) Output(output, @TypeOf(context)) {
return Output(output, @TypeOf(context)){
.context = context,
};
}
fn Output(comptime T: type) type {
const args = switch (@typeInfo(T)) {
.Fn => |f| f.args,
else => @compileError("output parameter is not a function"),
};
if (args.len != 2) {
@compileError("output function must take 2 arguments");
}
const at0 = args[0].arg_type orelse @compileError("output arg[0] does not have a type");
const at1 = args[1].arg_type orelse @compileError("output arg[1] does not have a type");
const arg1p = switch (@typeInfo(at1)) {
.Pointer => |p| p,
else => @compileError("output arg[1] is not a slice"),
};
if (arg1p.child != u8) @compileError("output arg[1] is not a u8 slice");
fn Output(comptime output_func: var, comptime Context: type) type {
return struct {
output: T,
context: at0,
context: Context,
fn write(self: *@This(), bytes: []const u8) !void {
try self.output(self.context, bytes);
pub const output = output_func;
fn write(self: @This(), bytes: []const u8) !void {
try output_func(self.context, bytes);
}
};
}