Fixes for stage1 compiler
This commit is contained in:
parent
181e57a631
commit
7d13b2546b
9 changed files with 68 additions and 41 deletions
|
@ -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(),
|
||||
);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue