Fixes for stage1 compiler

This commit is contained in:
jaina heartles 2022-11-10 01:53:09 -08:00
parent 181e57a631
commit 7d13b2546b
9 changed files with 68 additions and 41 deletions

View File

@ -276,7 +276,10 @@ fn ApiConn(comptime DbConn: type) type {
username,
password,
self.community.id,
.{ .invite_id = if (maybe_invite) |inv| inv.id else null, .email = opt.email },
.{
.invite_id = if (maybe_invite) |inv| @as(?Uuid, inv.id) else null,
.email = opt.email,
},
self.arena.allocator(),
);

View File

@ -94,7 +94,8 @@ pub const Actor = struct {
created_at: DateTime,
};
pub fn get(db: anytype, id: Uuid, alloc: std.mem.Allocator) !Actor {
pub const GetError = error{ NotFound, DatabaseFailure };
pub fn get(db: anytype, id: Uuid, alloc: std.mem.Allocator) GetError!Actor {
return db.queryRow(
Actor,
\\SELECT

View File

@ -83,11 +83,12 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
else => return error.DatabaseFailure,
}
const name = options.name orelse host;
db.insert("community", .{
.id = id,
.owner_id = null,
.host = host,
.name = options.name orelse host,
.name = name,
.scheme = scheme,
.kind = options.kind,
.created_at = DateTime.now(),
@ -262,14 +263,20 @@ pub fn query(db: anytype, args: QueryArgs, alloc: std.mem.Allocator) !QueryResul
_ = try builder.array.appendSlice("\nLIMIT $7");
const query_args = .{
args.owner_id,
args.like,
args.created_before,
args.created_after,
if (args.prev) |prev| prev.order_val else null,
if (args.prev) |prev| prev.id else null,
max_items,
const query_args = blk: {
const ord_val =
if (args.prev) |prev| @as(?QueryArgs.OrderVal, prev.order_val) else null;
const id =
if (args.prev) |prev| @as(?Uuid, prev.id) else null;
break :blk .{
args.owner_id,
args.like,
args.created_before,
args.created_after,
ord_val,
id,
max_items,
};
};
try builder.array.append(0);

View File

@ -71,7 +71,7 @@ pub fn create(db: anytype, created_by: Uuid, community_id: ?Uuid, options: Invit
.max_uses = options.max_uses,
.created_at = created_at,
.expires_at = if (options.lifespan) |lifespan|
created_at.add(lifespan)
@as(?DateTime, created_at.add(lifespan))
else
null,

View File

@ -32,7 +32,7 @@ pub fn parse(alloc: std.mem.Allocator, reader: anytype) !Request(@TypeOf(reader)
// discard \r\n
switch (try reader.readByte()) {
'\r' => if (try reader.readByte() != '\n') return error.BadRequest,
'\r' => if ((try reader.readByte()) != '\n') return error.BadRequest,
'\n' => {},
else => return error.BadRequest,
}

View File

@ -30,7 +30,7 @@ pub fn handshake(alloc: std.mem.Allocator, req: *http.Request, res: *http.Respon
if (std.ascii.indexOfIgnoreCase(connection, "Upgrade") == null) return error.BadHandshake;
const key_hdr = req.headers.get("Sec-WebSocket-Key") orelse return error.BadHandshake;
if (try std.base64.standard.Decoder.calcSizeForSlice(key_hdr) != 16) return error.BadHandshake;
if ((try std.base64.standard.Decoder.calcSizeForSlice(key_hdr)) != 16) return error.BadHandshake;
var key: [16]u8 = undefined;
std.base64.standard.Decoder.decode(&key, key_hdr) catch return error.BadHandshake;
@ -164,15 +164,15 @@ fn writeFrame(writer: anytype, header: FrameInfo, buf: []const u8) !void {
const initial_len: u7 = if (header.len < 126)
@intCast(u7, header.len)
else if (std.math.cast(u16, header.len)) |_|
126
@as(u7, 126)
else
127;
@as(u7, 127);
var hdr_buf = [2]u8{ 0, 0 };
hdr_buf[0] |= if (header.is_final) 0b1000_0000 else 0;
hdr_buf[0] |= if (header.is_final) @as(u8, 0b1000_0000) else 0;
hdr_buf[0] |= @as(u8, header.rsv) << 4;
hdr_buf[0] |= @enumToInt(header.opcode);
hdr_buf[1] |= if (header.masking_key) |_| 0b1000_0000 else 0;
hdr_buf[1] |= if (header.masking_key) |_| @as(u8, 0b1000_0000) else 0;
hdr_buf[1] |= initial_len;
try writer.writeAll(&hdr_buf);
if (initial_len == 126)

View File

@ -151,31 +151,37 @@ fn formatQueryParams(
return formatRecursive("", params, writer);
}
fn formatField(comptime name: []const u8, val: anytype, writer: anytype) !void {
// TODO: percent-encode this
_ = try switch (@TypeOf(val)) {
[]const u8 => blk: {
break :blk std.fmt.format(writer, "{s}={s}&", .{ name, val });
},
else => |U| blk: {
if (comptime std.meta.trait.isContainer(U) and std.meta.trait.hasFn("format")(U)) {
break :blk std.fmt.format(writer, "{s}={}&", .{ name, val });
}
break :blk switch (@typeInfo(U)) {
.Enum => std.fmt.format(writer, "{s}={s}&", .{ name, @tagName(val) }),
.Struct => formatRecursive(name ++ ".", val, writer),
else => std.fmt.format(writer, "{s}={}&", .{ name, val }),
};
},
};
}
fn formatRecursive(comptime prefix: []const u8, params: anytype, writer: anytype) !void {
inline for (std.meta.fields(@TypeOf(params))) |field| {
const val = @field(params, field.name);
const is_optional = comptime std.meta.trait.is(.Optional)(field.field_type);
const present = if (comptime is_optional) val != null else true;
if (present) {
const unwrapped = if (is_optional) val.? else val;
// TODO: percent-encode this
_ = try switch (@TypeOf(unwrapped)) {
[]const u8 => blk: {
break :blk std.fmt.format(writer, "{s}{s}={s}&", .{ prefix, field.name, unwrapped });
},
else => |U| blk: {
if (comptime std.meta.trait.isContainer(U) and std.meta.trait.hasFn("format")(U)) {
break :blk std.fmt.format(writer, "{s}{s}={}&", .{ prefix, field.name, unwrapped });
}
break :blk switch (@typeInfo(U)) {
.Enum => std.fmt.format(writer, "{s}{s}={s}&", .{ prefix, field.name, @tagName(unwrapped) }),
.Struct => formatRecursive(field.name ++ ".", unwrapped, writer),
else => std.fmt.format(writer, "{s}{s}={}&", .{ prefix, field.name, unwrapped }),
};
},
};
const name = prefix ++ field.name;
if (comptime std.meta.trait.is(.Optional)(field.field_type)) {
if (val) |v| {
try formatField(name, v, writer);
}
} else {
try formatField(name, val, writer);
}
}
}

View File

@ -186,10 +186,19 @@ pub const Db = struct {
var arena = std.heap.ArenaAllocator.init(alloc orelse return error.AllocatorRequired);
defer arena.deinit();
const params = try arena.allocator().alloc(?[*:0]const u8, args.len);
// TODO: The following is a fix for the stage1 compiler. remove this
//inline for (args) |arg, i| {
inline for (std.meta.fields(@TypeOf(args))) |field, i| {
const arg = @field(args, field.name);
params[i] = if (try common.prepareParamText(&arena, arg)) |slice|
// The stage1 compiler has issues with runtime branches that in any
// way involve compile time values
const maybe_slice = if (@import("builtin").zig_backend == .stage1)
common.prepareParamText(&arena, arg) catch unreachable
else
try common.prepareParamText(&arena, arg);
params[i] = if (maybe_slice) |slice|
slice.ptr
else
null;

View File

@ -118,6 +118,7 @@ pub const Db = struct {
};
if (@TypeOf(args) != void) {
// TODO: Fix for stage1 compiler
//inline for (args) |arg, i| {
inline for (std.meta.fields(@TypeOf(args))) |field, i| {
const arg = @field(args, field.name);