Skip to content

Commit

Permalink
node: API improvements (#97)
Browse files Browse the repository at this point in the history
- Add constant value helpers like intVal, boolVal,...
- safeCastNode now accepts an optional node pointer as well. A `null`
value will be converted into a properly typed `null` value of the target
node type.
  • Loading branch information
urso authored Oct 7, 2024
1 parent a6e363a commit 3f6f4a1
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions src/pgzx/node.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const std = @import("std");

const pg = @import("pgzx_pgsys");

const generated = @import("gen_node_tags");
Expand All @@ -8,6 +10,34 @@ pub const Tag = generated.Tag;

pub const List = collections.list.PointerListOf(pg.Node);

pub inline fn intVal(node: anytype) c_int {
const n = safeCastNode(pg.Integer, node) orelse {
@panic("Expected Integer node");
};
return n.ival;
}

pub inline fn floatVal(node: anytype) f64 {
const n = safeCastNode(pg.Float, node) orelse {
@panic("Expected Float node");
};
return std.fmt.parseFloat(f64, std.mem.span(n.fval));
}

pub inline fn strVal(node: anytype) [:0]const u8 {
const n = safeCastNode(pg.String, node) orelse {
@panic("Expected String node");
};
return std.mem.span(n.sval);
}

pub inline fn boolVal(node: anytype) bool {
const n = safeCastNode(pg.Boolean, node) orelse {
@panic("Expected Boolean node");
};
return n.boolval;
}

pub inline fn make(comptime T: type) *T {
const node: *pg.Node = @ptrCast(@alignCast(pg.palloc0fast(@sizeOf(T))));
node.*.type = @intFromEnum(mustFindTag(T));
Expand Down Expand Up @@ -48,6 +78,12 @@ pub inline fn castNode(comptime T: type, node: anytype) *T {
}

pub inline fn safeCastNode(comptime T: type, node: anytype) ?*T {
if (@typeInfo(@TypeOf(node)) == .Optional) {
if (node == null) {
return null;
}
}

if (tag(node) != generated.findTag(T)) {
return null;
}
Expand Down Expand Up @@ -76,8 +112,6 @@ inline fn checkIsPotentialNodePtr(node: anytype) void {
}

pub const TestSuite_Node = struct {
const std = @import("std");

pub fn testMakeAndTag() !void {
const node = make(pg.FdwRoutine);
try std.testing.expectEqual(tag(node), .FdwRoutine);
Expand Down

0 comments on commit 3f6f4a1

Please sign in to comment.