diff options
| author | 2023-11-23 21:35:16 +0100 | |
|---|---|---|
| committer | 2023-11-23 21:36:06 +0100 | |
| commit | 7d4d8fa55b98269666a8fc1f73795a78c10bd073 (patch) | |
| tree | 2c6570d8e0daefa52ac4e2e86f7ee95b8058b7a4 | |
| parent | add the isZigString helper (diff) | |
| download | zig-sqlite-7d4d8fa55b98269666a8fc1f73795a78c10bd073.tar.gz zig-sqlite-7d4d8fa55b98269666a8fc1f73795a78c10bd073.tar.xz zig-sqlite-7d4d8fa55b98269666a8fc1f73795a78c10bd073.zip | |
add the fasFn helper
| -rw-r--r-- | helpers.zig | 16 | ||||
| -rw-r--r-- | sqlite.zig | 2 | ||||
| -rw-r--r-- | vtab.zig | 20 |
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`. | ||
| 91 | pub 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 | } | ||
| @@ -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 | ||
| @@ -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 | ||