@@ -562,10 +562,7 @@ pub const Stream = c.luaL_Stream;
562562pub const Unsigned = c .lua_Unsigned ;
563563
564564/// The type of warning functions used by Lua to emit warnings
565- pub const CWarnFn = switch (lang ) {
566- .lua54 = > * const fn (data : ? * anyopaque , msg : [* c ]const u8 , to_cont : c_int ) callconv (.c ) void ,
567- else = > @compileError ("CWarnFn not defined" ),
568- };
565+ pub const CWarnFn = * const fn (data : ? * anyopaque , msg : [* c ]const u8 , to_cont : c_int ) callconv (.c ) void ;
569566
570567/// The type of the writer function used by `Lua.dump()`
571568pub const CWriterFn = * const fn (state : ? * LuaState , buf : ? * const anyopaque , size : usize , data : ? * anyopaque ) callconv (.c ) c_int ;
@@ -5157,21 +5154,30 @@ pub const Buffer = struct {
51575154
51585155// Helper functions to make the zlua API easier to use
51595156
5160- const Tuple = std .meta .Tuple ;
5161-
51625157fn TypeOfWrap (comptime function : anytype ) type {
5163- const Args = std .meta .ArgsTuple (@TypeOf (function ));
5164- return switch (Args ) {
5165- Tuple (&.{* Lua }) = > CFn ,
5166- Tuple (&.{ * Lua , Event , * DebugInfo }) = > CHookFn ,
5167- Tuple (&.{ * Lua , Status , Context }) = > CContFn ,
5168- Tuple (&.{ * Lua , * anyopaque }) = > CReaderFn ,
5169- Tuple (&.{* anyopaque }) = > CUserdataDtorFn ,
5170- Tuple (&.{ * Lua , i32 }) = > CInterruptCallbackFn ,
5171- Tuple (&.{[]const u8 }) = > CUserAtomCallbackFn ,
5172- Tuple (&.{ ? * anyopaque , []const u8 , bool }) = > CWarnFn ,
5173- Tuple (&.{ * Lua , []const u8 , * anyopaque }) = > CWriterFn ,
5174- else = > @compileError ("Unsupported function given to wrap '" ++ @typeName (@TypeOf (function )) ++ "'" ),
5158+ const params = @typeInfo (@TypeOf (function )).@"fn" .params ;
5159+ if (params .len == 1 ) {
5160+ if (params [0 ].type .? == * Lua ) return CFn ;
5161+ if (params [0 ].type .? == []const u8 ) return CUserAtomCallbackFn ;
5162+ if (params [0 ].type .? == * anyopaque ) return CUserdataDtorFn ;
5163+ }
5164+ if (params .len == 2 ) {
5165+ if (params [0 ].type .? == * Lua ) {
5166+ if (params [1 ].type .? == i32 ) return CInterruptCallbackFn ;
5167+ if (params [1 ].type .? == * anyopaque ) return CReaderFn ;
5168+ }
5169+ }
5170+ if (params .len == 3 ) {
5171+ if (params [0 ].type .? == ? * anyopaque and params [1 ].type .? == []const u8 and params [2 ].type .? == bool ) return CWarnFn ;
5172+ if (params [0 ].type .? == * Lua ) {
5173+ if (params [1 ].type .? == Event and params [2 ].type .? == * DebugInfo ) return CHookFn ;
5174+ if (params [1 ].type .? == Status and params [2 ].type .? == Context ) return CContFn ;
5175+ if (params [1 ].type .? == []const u8 and params [2 ].type .? == * anyopaque ) return CWriterFn ;
5176+ }
5177+ }
5178+ return {
5179+ @compileLog (@TypeOf (function ));
5180+ @compileError ("Unsupported function given to wrap." );
51755181 };
51765182}
51775183
@@ -5190,169 +5196,139 @@ fn TypeOfWrap(comptime function: anytype) type {
51905196/// Functions that accept a `*Lua` pointer also support returning error unions. For example,
51915197/// wrap also supports `fn (lua: *Lua) !i32` for a `CFn`.
51925198pub fn wrap (comptime function : anytype ) TypeOfWrap (function ) {
5193- const info = @typeInfo (@TypeOf (function ));
5194- if (info != .@"fn" ) {
5195- @compileError ("Wrap only accepts functions" );
5196- }
5197-
5198- const has_error_union = @typeInfo (info .@"fn" .return_type .? ) == .error_union ;
5199-
5200- const Args = std .meta .ArgsTuple (@TypeOf (function ));
5201- switch (Args ) {
5202- // CFn
5203- Tuple (&.{* Lua }) = > {
5204- return struct {
5205- fn inner (state : ? * LuaState ) callconv (.c ) c_int {
5206- // this is called by Lua, state should never be null
5207- var lua : * Lua = @ptrCast (state .? );
5208- if (has_error_union ) {
5209- return @call (.always_inline , function , .{lua }) catch | err | {
5210- lua .raiseErrorStr (@errorName (err ), .{});
5211- };
5212- } else {
5213- return @call (.always_inline , function , .{lua });
5214- }
5199+ const info = @typeInfo (@TypeOf (function )).@"fn" ;
5200+
5201+ const has_error_union = @typeInfo (info .return_type .? ) == .error_union ;
5202+
5203+ const Return = TypeOfWrap (function );
5204+ return switch (Return ) {
5205+ CFn = > struct {
5206+ fn inner (state : ? * LuaState ) callconv (.c ) c_int {
5207+ // this is called by Lua, state should never be null
5208+ var lua : * Lua = @ptrCast (state .? );
5209+ if (has_error_union ) {
5210+ return @call (.always_inline , function , .{lua }) catch | err | {
5211+ lua .raiseErrorStr (@errorName (err ), .{});
5212+ };
5213+ } else {
5214+ return @call (.always_inline , function , .{lua });
52155215 }
5216- }.inner ;
5217- },
5218- // CHookFn
5219- Tuple (&.{ * Lua , Event , * DebugInfo }) = > {
5220- return struct {
5221- fn inner (state : ? * LuaState , ar : ? * Debug ) callconv (.c ) void {
5222- // this is called by Lua, state should never be null
5223- var lua : * Lua = @ptrCast (state .? );
5224- var debug_info : DebugInfo = .{
5225- .current_line = if (ar .? .currentline == -1 ) null else ar .? .currentline ,
5226- .private = switch (lang ) {
5227- .lua51 , .luajit = > ar .? .i_ci ,
5228- else = > @ptrCast (ar .? .i_ci ),
5229- },
5216+ }
5217+ }.inner ,
5218+ CHookFn = > struct {
5219+ fn inner (state : ? * LuaState , ar : ? * Debug ) callconv (.c ) void {
5220+ // this is called by Lua, state should never be null
5221+ var lua : * Lua = @ptrCast (state .? );
5222+ var debug_info : DebugInfo = .{
5223+ .current_line = if (ar .? .currentline == -1 ) null else ar .? .currentline ,
5224+ .private = switch (lang ) {
5225+ .lua51 , .luajit = > ar .? .i_ci ,
5226+ else = > @ptrCast (ar .? .i_ci ),
5227+ },
5228+ };
5229+ if (has_error_union ) {
5230+ @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info }) catch | err | {
5231+ lua .raiseErrorStr (@errorName (err ), .{});
52305232 };
5231- if (has_error_union ) {
5232- @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info }) catch | err | {
5233- lua .raiseErrorStr (@errorName (err ), .{});
5234- };
5235- } else {
5236- @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info });
5237- }
5233+ } else {
5234+ @call (.always_inline , function , .{ lua , @as (Event , @enumFromInt (ar .? .event )), & debug_info });
52385235 }
5239- }.inner ;
5240- },
5241- // CContFn
5242- Tuple (&.{ * Lua , Status , Context }) = > {
5243- return struct {
5244- fn inner (state : ? * LuaState , status : c_int , ctx : Context ) callconv (.c ) c_int {
5245- // this is called by Lua, state should never be null
5246- var lua : * Lua = @ptrCast (state .? );
5247- if (has_error_union ) {
5248- return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx }) catch | err | {
5249- lua .raiseErrorStr (@errorName (err ), .{});
5250- };
5251- } else {
5252- return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx });
5253- }
5236+ }
5237+ }.inner ,
5238+ CContFn = > struct {
5239+ fn inner (state : ? * LuaState , status : c_int , ctx : Context ) callconv (.c ) c_int {
5240+ // this is called by Lua, state should never be null
5241+ var lua : * Lua = @ptrCast (state .? );
5242+ if (has_error_union ) {
5243+ return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx }) catch | err | {
5244+ lua .raiseErrorStr (@errorName (err ), .{});
5245+ };
5246+ } else {
5247+ return @call (.always_inline , function , .{ lua , @as (Status , @enumFromInt (status )), ctx });
52545248 }
5255- }.inner ;
5256- },
5257- // CReaderFn
5258- Tuple (&.{ * Lua , * anyopaque }) = > {
5259- return struct {
5260- fn inner (state : ? * LuaState , data : ? * anyopaque , size : [* c ]usize ) callconv (.c ) [* c ]const u8 {
5261- // this is called by Lua, state should never be null
5262- var lua : * Lua = @ptrCast (state .? );
5263- if (has_error_union ) {
5264- const result = @call (.always_inline , function , .{ lua , data .? }) catch | err | {
5265- lua .raiseErrorStr (@errorName (err ), .{});
5266- };
5267- if (result ) | buffer | {
5268- size .* = buffer .len ;
5269- return buffer .ptr ;
5270- } else {
5271- size .* = 0 ;
5272- return null ;
5273- }
5249+ }
5250+ }.inner ,
5251+ CReaderFn = > struct {
5252+ fn inner (state : ? * LuaState , data : ? * anyopaque , size : [* c ]usize ) callconv (.c ) [* c ]const u8 {
5253+ // this is called by Lua, state should never be null
5254+ var lua : * Lua = @ptrCast (state .? );
5255+ if (has_error_union ) {
5256+ const result = @call (.always_inline , function , .{ lua , data .? }) catch | err | {
5257+ lua .raiseErrorStr (@errorName (err ), .{});
5258+ };
5259+ if (result ) | buffer | {
5260+ size .* = buffer .len ;
5261+ return buffer .ptr ;
52745262 } else {
5275- if (@call (.always_inline , function , .{ lua , data .? })) | buffer | {
5276- size .* = buffer .len ;
5277- return buffer .ptr ;
5278- } else {
5279- size .* = 0 ;
5280- return null ;
5281- }
5263+ size .* = 0 ;
5264+ return null ;
52825265 }
5283- }
5284- }.inner ;
5285- },
5286- // CUserdataDtorFn
5287- Tuple (&.{* anyopaque }) = > {
5288- return struct {
5289- fn inner (userdata : * anyopaque ) callconv (.c ) void {
5290- return @call (.always_inline , function , .{userdata });
5291- }
5292- }.inner ;
5293- },
5294- // CInterruptCallbackFn
5295- Tuple (&.{ * Lua , i32 }) = > {
5296- return struct {
5297- fn inner (state : ? * LuaState , gc : c_int ) callconv (.c ) void {
5298- // this is called by Lua, state should never be null
5299- var lua : * Lua = @ptrCast (state .? );
5300- if (has_error_union ) {
5301- @call (.always_inline , function , .{ lua , gc }) catch | err | {
5302- lua .raiseErrorStr (@errorName (err ), .{});
5303- };
5266+ } else {
5267+ if (@call (.always_inline , function , .{ lua , data .? })) | buffer | {
5268+ size .* = buffer .len ;
5269+ return buffer .ptr ;
53045270 } else {
5305- @call (.always_inline , function , .{ lua , gc });
5271+ size .* = 0 ;
5272+ return null ;
53065273 }
53075274 }
5308- }.inner ;
5309- },
5310- // CUserAtomCallbackFn
5311- Tuple (&.{[]const u8 }) = > {
5312- return struct {
5313- fn inner (str : [* c ]const u8 , len : usize ) callconv (.c ) i16 {
5314- if (str ) | s | {
5315- const buf = s [0.. len ];
5316- return @call (.always_inline , function , .{buf });
5317- }
5318- return -1 ;
5275+ }
5276+ }.inner ,
5277+ CUserdataDtorFn = > struct {
5278+ fn inner (userdata : * anyopaque ) callconv (.c ) void {
5279+ return @call (.always_inline , function , .{userdata });
5280+ }
5281+ }.inner ,
5282+ CInterruptCallbackFn = > struct {
5283+ fn inner (state : ? * LuaState , gc : c_int ) callconv (.c ) void {
5284+ // this is called by Lua, state should never be null
5285+ var lua : * Lua = @ptrCast (state .? );
5286+ if (has_error_union ) {
5287+ @call (.always_inline , function , .{ lua , gc }) catch | err | {
5288+ lua .raiseErrorStr (@errorName (err ), .{});
5289+ };
5290+ } else {
5291+ @call (.always_inline , function , .{ lua , gc });
53195292 }
5320- }.inner ;
5321- },
5322- // CWarnFn
5323- Tuple (&.{ ? * anyopaque , []const u8 , bool }) = > {
5324- return struct {
5325- fn inner (data : ? * anyopaque , msg : [* c ]const u8 , to_cont : c_int ) callconv (.c ) void {
5326- // warning messages emitted from Lua should be null-terminated for display
5327- const message = std .mem .span (@as ([* :0 ]const u8 , @ptrCast (msg )));
5328- @call (.always_inline , function , .{ data , message , to_cont != 0 });
5293+ }
5294+ }.inner ,
5295+ CUserAtomCallbackFn = > struct {
5296+ fn inner (str : [* c ]const u8 , len : usize ) callconv (.c ) i16 {
5297+ if (str ) | s | {
5298+ const buf = s [0.. len ];
5299+ return @call (.always_inline , function , .{buf });
53295300 }
5330- }.inner ;
5331- },
5332- // CWriterFn
5333- Tuple (&.{ * Lua , []const u8 , * anyopaque }) = > {
5334- return struct {
5335- fn inner (state : ? * LuaState , buf : ? * const anyopaque , size : usize , data : ? * anyopaque ) callconv (.c ) c_int {
5336- // this is called by Lua, state should never be null
5337- var lua : * Lua = @ptrCast (state .? );
5338- const buffer = @as ([* ]const u8 , @ptrCast (buf ))[0.. size ];
5339-
5340- const result = if (has_error_union ) blk : {
5341- break :blk @call (.always_inline , function , .{ lua , buffer , data .? }) catch | err | {
5342- lua .raiseErrorStr (@errorName (err ), .{});
5343- };
5344- } else blk : {
5345- break :blk @call (.always_inline , function , .{ lua , buffer , data .? });
5301+ return -1 ;
5302+ }
5303+ }.inner ,
5304+ CWarnFn = > if (lang != .lua54 ) @compileError ("CWarnFn is only valid in Lua >= 5.4" ) else struct {
5305+ fn inner (data : ? * anyopaque , msg : [* c ]const u8 , to_cont : c_int ) callconv (.c ) void {
5306+ // warning messages emitted from Lua should be null-terminated for display
5307+ const message = std .mem .span (@as ([* :0 ]const u8 , @ptrCast (msg )));
5308+ @call (.always_inline , function , .{ data , message , to_cont != 0 });
5309+ }
5310+ }.inner ,
5311+ CWriterFn = > struct {
5312+ fn inner (state : ? * LuaState , buf : ? * const anyopaque , size : usize , data : ? * anyopaque ) callconv (.c ) c_int {
5313+ // this is called by Lua, state should never be null
5314+ var lua : * Lua = @ptrCast (state .? );
5315+ const buffer = @as ([* ]const u8 , @ptrCast (buf ))[0.. size ];
5316+
5317+ const result = if (has_error_union ) blk : {
5318+ break :blk @call (.always_inline , function , .{ lua , buffer , data .? }) catch | err | {
5319+ lua .raiseErrorStr (@errorName (err ), .{});
53465320 };
5321+ } else blk : {
5322+ break :blk @call (.always_inline , function , .{ lua , buffer , data .? });
5323+ };
53475324
5348- // it makes more sense for the inner writer function to return false for failure,
5349- // so negate the result here
5350- return @intFromBool (! result );
5351- }
5352- }.inner ;
5353- },
5354- else = > @compileError ("Unsupported function given to wrap '" ++ @typeName (@TypeOf (function )) ++ "'" ),
5355- }
5325+ // it makes more sense for the inner writer function to return false for failure,
5326+ // so negate the result here
5327+ return @intFromBool (! result );
5328+ }
5329+ }.inner ,
5330+ else = > unreachable ,
5331+ };
53565332}
53575333
53585334/// Zig wrapper for Luau lua_CompileOptions that uses the same defaults as Luau if
0 commit comments