diff options
Diffstat (limited to 'vtab.zig')
| -rw-r--r-- | vtab.zig | 49 |
1 files changed, 29 insertions, 20 deletions
| @@ -16,6 +16,15 @@ const helpers = @import("helpers.zig"); | |||
| 16 | 16 | ||
| 17 | const logger = std.log.scoped(.vtab); | 17 | const logger = std.log.scoped(.vtab); |
| 18 | 18 | ||
| 19 | fn hasDecls(comptime T: type, comptime names: anytype) bool { | ||
| 20 | inline for (names) |name| { | ||
| 21 | if (!@hasDecl(T, name)) { | ||
| 22 | return false; | ||
| 23 | } | ||
| 24 | } | ||
| 25 | return true; | ||
| 26 | } | ||
| 27 | |||
| 19 | /// ModuleContext contains state that is needed by all implementations of virtual tables. | 28 | /// ModuleContext contains state that is needed by all implementations of virtual tables. |
| 20 | /// | 29 | /// |
| 21 | /// Currently there's only an allocator. | 30 | /// Currently there's only an allocator. |
| @@ -301,7 +310,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 301 | 310 | ||
| 302 | // Validate the `init` function | 311 | // Validate the `init` function |
| 303 | { | 312 | { |
| 304 | if (!meta.trait.hasDecls(Cursor, .{"InitError"})) { | 313 | if (!comptime hasDecls(Cursor, .{"InitError"})) { |
| 305 | @compileError("the Cursor type must declare a InitError error set for the init function"); | 314 | @compileError("the Cursor type must declare a InitError error set for the init function"); |
| 306 | } | 315 | } |
| 307 | 316 | ||
| @@ -309,7 +318,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 309 | \\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` |
| 310 | ; | 319 | ; |
| 311 | 320 | ||
| 312 | if (!meta.trait.hasFn("init")(Cursor)) { | 321 | if (!comptime helpers.hasFn(Cursor, "init")) { |
| 313 | @compileError("the Cursor type must have an init function, " ++ error_message); | 322 | @compileError("the Cursor type must have an init function, " ++ error_message); |
| 314 | } | 323 | } |
| 315 | 324 | ||
| @@ -327,7 +336,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 327 | \\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` |
| 328 | ; | 337 | ; |
| 329 | 338 | ||
| 330 | if (!meta.trait.hasFn("deinit")(Cursor)) { | 339 | if (!comptime helpers.hasFn(Cursor, "deinit")) { |
| 331 | @compileError("the Cursor type must have a deinit function, " ++ error_message); | 340 | @compileError("the Cursor type must have a deinit function, " ++ error_message); |
| 332 | } | 341 | } |
| 333 | 342 | ||
| @@ -340,7 +349,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 340 | 349 | ||
| 341 | // Validate the `next` function | 350 | // Validate the `next` function |
| 342 | { | 351 | { |
| 343 | if (!meta.trait.hasDecls(Cursor, .{"NextError"})) { | 352 | if (!comptime hasDecls(Cursor, .{"NextError"})) { |
| 344 | @compileError("the Cursor type must declare a NextError error set for the next function"); | 353 | @compileError("the Cursor type must declare a NextError error set for the next function"); |
| 345 | } | 354 | } |
| 346 | 355 | ||
| @@ -348,7 +357,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 348 | \\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` |
| 349 | ; | 358 | ; |
| 350 | 359 | ||
| 351 | if (!meta.trait.hasFn("next")(Cursor)) { | 360 | if (!comptime helpers.hasFn(Cursor, "next")) { |
| 352 | @compileError("the Cursor type must have a next function, " ++ error_message); | 361 | @compileError("the Cursor type must have a next function, " ++ error_message); |
| 353 | } | 362 | } |
| 354 | 363 | ||
| @@ -362,7 +371,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 362 | 371 | ||
| 363 | // Validate the `hasNext` function | 372 | // Validate the `hasNext` function |
| 364 | { | 373 | { |
| 365 | if (!meta.trait.hasDecls(Cursor, .{"HasNextError"})) { | 374 | if (!comptime hasDecls(Cursor, .{"HasNextError"})) { |
| 366 | @compileError("the Cursor type must declare a HasNextError error set for the hasNext function"); | 375 | @compileError("the Cursor type must declare a HasNextError error set for the hasNext function"); |
| 367 | } | 376 | } |
| 368 | 377 | ||
| @@ -370,7 +379,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 370 | \\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` |
| 371 | ; | 380 | ; |
| 372 | 381 | ||
| 373 | if (!meta.trait.hasFn("hasNext")(Cursor)) { | 382 | if (!comptime helpers.hasFn(Cursor, "hasNext")) { |
| 374 | @compileError("the Cursor type must have a hasNext function, " ++ error_message); | 383 | @compileError("the Cursor type must have a hasNext function, " ++ error_message); |
| 375 | } | 384 | } |
| 376 | 385 | ||
| @@ -384,7 +393,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 384 | 393 | ||
| 385 | // Validate the `filter` function | 394 | // Validate the `filter` function |
| 386 | { | 395 | { |
| 387 | if (!meta.trait.hasDecls(Cursor, .{"FilterError"})) { | 396 | if (!comptime hasDecls(Cursor, .{"FilterError"})) { |
| 388 | @compileError("the Cursor type must declare a FilterError error set for the filter function"); | 397 | @compileError("the Cursor type must declare a FilterError error set for the filter function"); |
| 389 | } | 398 | } |
| 390 | 399 | ||
| @@ -392,7 +401,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 392 | \\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` |
| 393 | ; | 402 | ; |
| 394 | 403 | ||
| 395 | if (!meta.trait.hasFn("filter")(Cursor)) { | 404 | if (!comptime helpers.hasFn(Cursor, "filter")) { |
| 396 | @compileError("the Cursor type must have a filter function, " ++ error_message); | 405 | @compileError("the Cursor type must have a filter function, " ++ error_message); |
| 397 | } | 406 | } |
| 398 | 407 | ||
| @@ -408,10 +417,10 @@ fn validateCursorType(comptime Table: type) void { | |||
| 408 | 417 | ||
| 409 | // Validate the `column` function | 418 | // Validate the `column` function |
| 410 | { | 419 | { |
| 411 | if (!meta.trait.hasDecls(Cursor, .{"ColumnError"})) { | 420 | if (!comptime hasDecls(Cursor, .{"ColumnError"})) { |
| 412 | @compileError("the Cursor type must declare a ColumnError error set for the column function"); | 421 | @compileError("the Cursor type must declare a ColumnError error set for the column function"); |
| 413 | } | 422 | } |
| 414 | if (!meta.trait.hasDecls(Cursor, .{"Column"})) { | 423 | if (!comptime hasDecls(Cursor, .{"Column"})) { |
| 415 | @compileError("the Cursor type must declare a Column type for the return type of the column function"); | 424 | @compileError("the Cursor type must declare a Column type for the return type of the column function"); |
| 416 | } | 425 | } |
| 417 | 426 | ||
| @@ -419,7 +428,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 419 | \\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` |
| 420 | ; | 429 | ; |
| 421 | 430 | ||
| 422 | if (!meta.trait.hasFn("column")(Cursor)) { | 431 | if (!comptime helpers.hasFn(Cursor, "column")) { |
| 423 | @compileError("the Cursor type must have a column function, " ++ error_message); | 432 | @compileError("the Cursor type must have a column function, " ++ error_message); |
| 424 | } | 433 | } |
| 425 | 434 | ||
| @@ -434,7 +443,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 434 | 443 | ||
| 435 | // Validate the `rowId` function | 444 | // Validate the `rowId` function |
| 436 | { | 445 | { |
| 437 | if (!meta.trait.hasDecls(Cursor, .{"RowIDError"})) { | 446 | if (!comptime hasDecls(Cursor, .{"RowIDError"})) { |
| 438 | @compileError("the Cursor type must declare a RowIDError error set for the rowId function"); | 447 | @compileError("the Cursor type must declare a RowIDError error set for the rowId function"); |
| 439 | } | 448 | } |
| 440 | 449 | ||
| @@ -442,7 +451,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 442 | \\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` |
| 443 | ; | 452 | ; |
| 444 | 453 | ||
| 445 | if (!meta.trait.hasFn("rowId")(Cursor)) { | 454 | if (!comptime helpers.hasFn(Cursor, "rowId")) { |
| 446 | @compileError("the Cursor type must have a rowId function, " ++ error_message); | 455 | @compileError("the Cursor type must have a rowId function, " ++ error_message); |
| 447 | } | 456 | } |
| 448 | 457 | ||
| @@ -459,7 +468,7 @@ fn validateCursorType(comptime Table: type) void { | |||
| 459 | fn validateTableType(comptime Table: type) void { | 468 | fn validateTableType(comptime Table: type) void { |
| 460 | // Validate the `init` function | 469 | // Validate the `init` function |
| 461 | { | 470 | { |
| 462 | if (!meta.trait.hasDecls(Table, .{"InitError"})) { | 471 | if (!comptime hasDecls(Table, .{"InitError"})) { |
| 463 | @compileError("the Table type must declare a InitError error set for the init function"); | 472 | @compileError("the Table type must declare a InitError error set for the init function"); |
| 464 | } | 473 | } |
| 465 | 474 | ||
| @@ -467,7 +476,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 467 | \\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` |
| 468 | ; | 477 | ; |
| 469 | 478 | ||
| 470 | if (!meta.trait.hasFn("init")(Table)) { | 479 | if (!comptime helpers.hasFn(Table, "init")) { |
| 471 | @compileError("the Table type must have a init function, " ++ error_message); | 480 | @compileError("the Table type must have a init function, " ++ error_message); |
| 472 | } | 481 | } |
| 473 | 482 | ||
| @@ -487,7 +496,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 487 | \\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` |
| 488 | ; | 497 | ; |
| 489 | 498 | ||
| 490 | if (!meta.trait.hasFn("deinit")(Table)) { | 499 | if (!comptime helpers.hasFn(Table, "deinit")) { |
| 491 | @compileError("the Table type must have a deinit function, " ++ error_message); | 500 | @compileError("the Table type must have a deinit function, " ++ error_message); |
| 492 | } | 501 | } |
| 493 | 502 | ||
| @@ -501,7 +510,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 501 | 510 | ||
| 502 | // Validate the `buildBestIndex` function | 511 | // Validate the `buildBestIndex` function |
| 503 | { | 512 | { |
| 504 | if (!meta.trait.hasDecls(Table, .{"BuildBestIndexError"})) { | 513 | if (!comptime hasDecls(Table, .{"BuildBestIndexError"})) { |
| 505 | @compileError("the Cursor type must declare a BuildBestIndexError error set for the buildBestIndex function"); | 514 | @compileError("the Cursor type must declare a BuildBestIndexError error set for the buildBestIndex function"); |
| 506 | } | 515 | } |
| 507 | 516 | ||
| @@ -509,7 +518,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 509 | \\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` |
| 510 | ; | 519 | ; |
| 511 | 520 | ||
| 512 | if (!meta.trait.hasFn("buildBestIndex")(Table)) { | 521 | if (!comptime helpers.hasFn(Table, "buildBestIndex")) { |
| 513 | @compileError("the Table type must have a buildBestIndex function, " ++ error_message); | 522 | @compileError("the Table type must have a buildBestIndex function, " ++ error_message); |
| 514 | } | 523 | } |
| 515 | 524 | ||
| @@ -522,7 +531,7 @@ fn validateTableType(comptime Table: type) void { | |||
| 522 | if (info.return_type.? != Table.BuildBestIndexError!void) @compileError(error_message); | 531 | if (info.return_type.? != Table.BuildBestIndexError!void) @compileError(error_message); |
| 523 | } | 532 | } |
| 524 | 533 | ||
| 525 | if (!meta.trait.hasDecls(Table, .{"Cursor"})) { | 534 | if (!comptime hasDecls(Table, .{"Cursor"})) { |
| 526 | @compileError("the Table type must declare a Cursor type"); | 535 | @compileError("the Table type must declare a Cursor type"); |
| 527 | } | 536 | } |
| 528 | } | 537 | } |