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,
|
username,
|
||||||
password,
|
password,
|
||||||
self.community.id,
|
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(),
|
self.arena.allocator(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,8 @@ pub const Actor = struct {
|
||||||
created_at: DateTime,
|
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(
|
return db.queryRow(
|
||||||
Actor,
|
Actor,
|
||||||
\\SELECT
|
\\SELECT
|
||||||
|
|
|
@ -83,11 +83,12 @@ pub fn create(db: anytype, origin: []const u8, options: CreateOptions, alloc: st
|
||||||
else => return error.DatabaseFailure,
|
else => return error.DatabaseFailure,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const name = options.name orelse host;
|
||||||
db.insert("community", .{
|
db.insert("community", .{
|
||||||
.id = id,
|
.id = id,
|
||||||
.owner_id = null,
|
.owner_id = null,
|
||||||
.host = host,
|
.host = host,
|
||||||
.name = options.name orelse host,
|
.name = name,
|
||||||
.scheme = scheme,
|
.scheme = scheme,
|
||||||
.kind = options.kind,
|
.kind = options.kind,
|
||||||
.created_at = DateTime.now(),
|
.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");
|
_ = try builder.array.appendSlice("\nLIMIT $7");
|
||||||
|
|
||||||
const query_args = .{
|
const query_args = blk: {
|
||||||
args.owner_id,
|
const ord_val =
|
||||||
args.like,
|
if (args.prev) |prev| @as(?QueryArgs.OrderVal, prev.order_val) else null;
|
||||||
args.created_before,
|
const id =
|
||||||
args.created_after,
|
if (args.prev) |prev| @as(?Uuid, prev.id) else null;
|
||||||
if (args.prev) |prev| prev.order_val else null,
|
break :blk .{
|
||||||
if (args.prev) |prev| prev.id else null,
|
args.owner_id,
|
||||||
max_items,
|
args.like,
|
||||||
|
args.created_before,
|
||||||
|
args.created_after,
|
||||||
|
ord_val,
|
||||||
|
id,
|
||||||
|
max_items,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
try builder.array.append(0);
|
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,
|
.max_uses = options.max_uses,
|
||||||
.created_at = created_at,
|
.created_at = created_at,
|
||||||
.expires_at = if (options.lifespan) |lifespan|
|
.expires_at = if (options.lifespan) |lifespan|
|
||||||
created_at.add(lifespan)
|
@as(?DateTime, created_at.add(lifespan))
|
||||||
else
|
else
|
||||||
null,
|
null,
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub fn parse(alloc: std.mem.Allocator, reader: anytype) !Request(@TypeOf(reader)
|
||||||
|
|
||||||
// discard \r\n
|
// discard \r\n
|
||||||
switch (try reader.readByte()) {
|
switch (try reader.readByte()) {
|
||||||
'\r' => if (try reader.readByte() != '\n') return error.BadRequest,
|
'\r' => if ((try reader.readByte()) != '\n') return error.BadRequest,
|
||||||
'\n' => {},
|
'\n' => {},
|
||||||
else => return error.BadRequest,
|
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;
|
if (std.ascii.indexOfIgnoreCase(connection, "Upgrade") == null) return error.BadHandshake;
|
||||||
|
|
||||||
const key_hdr = req.headers.get("Sec-WebSocket-Key") orelse 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;
|
var key: [16]u8 = undefined;
|
||||||
std.base64.standard.Decoder.decode(&key, key_hdr) catch return error.BadHandshake;
|
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)
|
const initial_len: u7 = if (header.len < 126)
|
||||||
@intCast(u7, header.len)
|
@intCast(u7, header.len)
|
||||||
else if (std.math.cast(u16, header.len)) |_|
|
else if (std.math.cast(u16, header.len)) |_|
|
||||||
126
|
@as(u7, 126)
|
||||||
else
|
else
|
||||||
127;
|
@as(u7, 127);
|
||||||
|
|
||||||
var hdr_buf = [2]u8{ 0, 0 };
|
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] |= @as(u8, header.rsv) << 4;
|
||||||
hdr_buf[0] |= @enumToInt(header.opcode);
|
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;
|
hdr_buf[1] |= initial_len;
|
||||||
try writer.writeAll(&hdr_buf);
|
try writer.writeAll(&hdr_buf);
|
||||||
if (initial_len == 126)
|
if (initial_len == 126)
|
||||||
|
|
|
@ -151,31 +151,37 @@ fn formatQueryParams(
|
||||||
return formatRecursive("", params, writer);
|
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 {
|
fn formatRecursive(comptime prefix: []const u8, params: anytype, writer: anytype) !void {
|
||||||
inline for (std.meta.fields(@TypeOf(params))) |field| {
|
inline for (std.meta.fields(@TypeOf(params))) |field| {
|
||||||
const val = @field(params, field.name);
|
const val = @field(params, field.name);
|
||||||
const is_optional = comptime std.meta.trait.is(.Optional)(field.field_type);
|
const name = prefix ++ field.name;
|
||||||
const present = if (comptime is_optional) val != null else true;
|
if (comptime std.meta.trait.is(.Optional)(field.field_type)) {
|
||||||
if (present) {
|
if (val) |v| {
|
||||||
const unwrapped = if (is_optional) val.? else val;
|
try formatField(name, v, writer);
|
||||||
// TODO: percent-encode this
|
}
|
||||||
_ = try switch (@TypeOf(unwrapped)) {
|
} else {
|
||||||
[]const u8 => blk: {
|
try formatField(name, val, writer);
|
||||||
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 }),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,10 +186,19 @@ pub const Db = struct {
|
||||||
var arena = std.heap.ArenaAllocator.init(alloc orelse return error.AllocatorRequired);
|
var arena = std.heap.ArenaAllocator.init(alloc orelse return error.AllocatorRequired);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const params = try arena.allocator().alloc(?[*:0]const u8, args.len);
|
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 (args) |arg, i| {
|
||||||
inline for (std.meta.fields(@TypeOf(args))) |field, i| {
|
inline for (std.meta.fields(@TypeOf(args))) |field, i| {
|
||||||
const arg = @field(args, field.name);
|
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
|
slice.ptr
|
||||||
else
|
else
|
||||||
null;
|
null;
|
||||||
|
|
|
@ -118,6 +118,7 @@ pub const Db = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (@TypeOf(args) != void) {
|
if (@TypeOf(args) != void) {
|
||||||
|
// TODO: Fix for stage1 compiler
|
||||||
//inline for (args) |arg, i| {
|
//inline for (args) |arg, i| {
|
||||||
inline for (std.meta.fields(@TypeOf(args))) |field, i| {
|
inline for (std.meta.fields(@TypeOf(args))) |field, i| {
|
||||||
const arg = @field(args, field.name);
|
const arg = @field(args, field.name);
|
||||||
|
|
Loading…
Reference in a new issue