summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--helpers.zig16
-rw-r--r--sqlite.zig2
-rw-r--r--vtab.zig20
3 files changed, 27 insertions, 11 deletions
diff --git a/helpers.zig b/helpers.zig
index 1a56231..7bb695e 100644
--- a/helpers.zig
+++ b/helpers.zig
@@ -86,3 +86,19 @@ fn sliceFromValue(sqlite_value: *c.sqlite3_value) []const u8 {
86 86
87 return value[0..size]; 87 return value[0..size];
88} 88}
89
90// Returns true if the type T has a function named `name`.
91pub fn hasFn(comptime T: type, comptime name: []const u8) bool {
92 if (!@hasDecl(T, name)) {
93 return false;
94 }
95
96 const decl = @field(T, name);
97 const decl_type = @TypeOf(decl);
98 const decl_type_info = @typeInfo(decl_type);
99
100 return switch (decl_type_info) {
101 .Fn => true,
102 else => false,
103 };
104}
diff --git a/sqlite.zig b/sqlite.zig
index c3ecb84..3759884 100644
--- a/sqlite.zig
+++ b/sqlite.zig
@@ -1693,7 +1693,7 @@ pub const DynamicStatement = struct {
1693 try self.bindField(info.backing_integer.?, options, field_name, i, @as(info.backing_integer.?, @bitCast(field))); 1693 try self.bindField(info.backing_integer.?, options, field_name, i, @as(info.backing_integer.?, @bitCast(field)));
1694 return; 1694 return;
1695 } 1695 }
1696 if (!comptime std.meta.trait.hasFn("bindField")(FieldType)) { 1696 if (!comptime helpers.hasFn(FieldType, "bindField")) {
1697 @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType) ++ ", consider implementing the bindField() method"); 1697 @compileError("cannot bind field " ++ field_name ++ " of type " ++ @typeName(FieldType) ++ ", consider implementing the bindField() method");
1698 } 1698 }
1699 1699
diff --git a/vtab.zig b/vtab.zig
index 7c2dafe..eb73990 100644
--- a/vtab.zig
+++ b/vtab.zig
@@ -318,7 +318,7 @@ fn validateCursorType(comptime Table: type) void {
318 \\the Cursor.init function must have the signature `fn init(allocator: std.mem.Allocator, parent: *Table) InitError!*Cursor` 318 \\the Cursor.init function must have the signature `fn init(allocator: std.mem.Allocator, parent: *Table) InitError!*Cursor`
319 ; 319 ;
320 320
321 if (!meta.trait.hasFn("init")(Cursor)) { 321 if (!comptime helpers.hasFn(Cursor, "init")) {
322 @compileError("the Cursor type must have an init function, " ++ error_message); 322 @compileError("the Cursor type must have an init function, " ++ error_message);
323 } 323 }
324 324
@@ -336,7 +336,7 @@ fn validateCursorType(comptime Table: type) void {
336 \\the Cursor.deinit function must have the signature `fn deinit(cursor: *Cursor) void` 336 \\the Cursor.deinit function must have the signature `fn deinit(cursor: *Cursor) void`
337 ; 337 ;
338 338
339 if (!meta.trait.hasFn("deinit")(Cursor)) { 339 if (!comptime helpers.hasFn(Cursor, "deinit")) {
340 @compileError("the Cursor type must have a deinit function, " ++ error_message); 340 @compileError("the Cursor type must have a deinit function, " ++ error_message);
341 } 341 }
342 342
@@ -357,7 +357,7 @@ fn validateCursorType(comptime Table: type) void {
357 \\the Cursor.next function must have the signature `fn next(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics) NextError!void` 357 \\the Cursor.next function must have the signature `fn next(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics) NextError!void`
358 ; 358 ;
359 359
360 if (!meta.trait.hasFn("next")(Cursor)) { 360 if (!comptime helpers.hasFn(Cursor, "next")) {
361 @compileError("the Cursor type must have a next function, " ++ error_message); 361 @compileError("the Cursor type must have a next function, " ++ error_message);
362 } 362 }
363 363
@@ -379,7 +379,7 @@ fn validateCursorType(comptime Table: type) void {
379 \\the Cursor.hasNext function must have the signature `fn hasNext(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics) HasNextError!bool` 379 \\the Cursor.hasNext function must have the signature `fn hasNext(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics) HasNextError!bool`
380 ; 380 ;
381 381
382 if (!meta.trait.hasFn("hasNext")(Cursor)) { 382 if (!comptime helpers.hasFn(Cursor, "hasNext")) {
383 @compileError("the Cursor type must have a hasNext function, " ++ error_message); 383 @compileError("the Cursor type must have a hasNext function, " ++ error_message);
384 } 384 }
385 385
@@ -401,7 +401,7 @@ fn validateCursorType(comptime Table: type) void {
401 \\the Cursor.filter function must have the signature `fn filter(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics, index: sqlite.vtab.IndexIdentifier, args: []FilterArg) FilterError!bool` 401 \\the Cursor.filter function must have the signature `fn filter(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics, index: sqlite.vtab.IndexIdentifier, args: []FilterArg) FilterError!bool`
402 ; 402 ;
403 403
404 if (!meta.trait.hasFn("filter")(Cursor)) { 404 if (!comptime helpers.hasFn(Cursor, "filter")) {
405 @compileError("the Cursor type must have a filter function, " ++ error_message); 405 @compileError("the Cursor type must have a filter function, " ++ error_message);
406 } 406 }
407 407
@@ -428,7 +428,7 @@ fn validateCursorType(comptime Table: type) void {
428 \\the Cursor.column function must have the signature `fn column(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics, column_number: i32) ColumnError!Column` 428 \\the Cursor.column function must have the signature `fn column(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics, column_number: i32) ColumnError!Column`
429 ; 429 ;
430 430
431 if (!meta.trait.hasFn("column")(Cursor)) { 431 if (!comptime helpers.hasFn(Cursor, "column")) {
432 @compileError("the Cursor type must have a column function, " ++ error_message); 432 @compileError("the Cursor type must have a column function, " ++ error_message);
433 } 433 }
434 434
@@ -451,7 +451,7 @@ fn validateCursorType(comptime Table: type) void {
451 \\the Cursor.rowId function must have the signature `fn rowId(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics) RowIDError!i64` 451 \\the Cursor.rowId function must have the signature `fn rowId(cursor: *Cursor, diags: *sqlite.vtab.VTabDiagnostics) RowIDError!i64`
452 ; 452 ;
453 453
454 if (!meta.trait.hasFn("rowId")(Cursor)) { 454 if (!comptime helpers.hasFn(Cursor, "rowId")) {
455 @compileError("the Cursor type must have a rowId function, " ++ error_message); 455 @compileError("the Cursor type must have a rowId function, " ++ error_message);
456 } 456 }
457 457
@@ -476,7 +476,7 @@ fn validateTableType(comptime Table: type) void {
476 \\the Table.init function must have the signature `fn init(allocator: std.mem.Allocator, diags: *sqlite.vtab.VTabDiagnostics, args: []const ModuleArgument) InitError!*Table` 476 \\the Table.init function must have the signature `fn init(allocator: std.mem.Allocator, diags: *sqlite.vtab.VTabDiagnostics, args: []const ModuleArgument) InitError!*Table`
477 ; 477 ;
478 478
479 if (!meta.trait.hasFn("init")(Table)) { 479 if (!comptime helpers.hasFn(Table, "init")) {
480 @compileError("the Table type must have a init function, " ++ error_message); 480 @compileError("the Table type must have a init function, " ++ error_message);
481 } 481 }
482 482
@@ -496,7 +496,7 @@ fn validateTableType(comptime Table: type) void {
496 \\the Table.deinit function must have the signature `fn deinit(table: *Table, allocator: std.mem.Allocator) void` 496 \\the Table.deinit function must have the signature `fn deinit(table: *Table, allocator: std.mem.Allocator) void`
497 ; 497 ;
498 498
499 if (!meta.trait.hasFn("deinit")(Table)) { 499 if (!comptime helpers.hasFn(Table, "deinit")) {
500 @compileError("the Table type must have a deinit function, " ++ error_message); 500 @compileError("the Table type must have a deinit function, " ++ error_message);
501 } 501 }
502 502
@@ -518,7 +518,7 @@ fn validateTableType(comptime Table: type) void {
518 \\the Table.buildBestIndex function must have the signature `fn buildBestIndex(table: *Table, diags: *sqlite.vtab.VTabDiagnostics, builder: *sqlite.vtab.BestIndexBuilder) BuildBestIndexError!void` 518 \\the Table.buildBestIndex function must have the signature `fn buildBestIndex(table: *Table, diags: *sqlite.vtab.VTabDiagnostics, builder: *sqlite.vtab.BestIndexBuilder) BuildBestIndexError!void`
519 ; 519 ;
520 520
521 if (!meta.trait.hasFn("buildBestIndex")(Table)) { 521 if (!comptime helpers.hasFn(Table, "buildBestIndex")) {
522 @compileError("the Table type must have a buildBestIndex function, " ++ error_message); 522 @compileError("the Table type must have a buildBestIndex function, " ++ error_message);
523 } 523 }
524 524