@@ -2048,6 +2048,22 @@ pub const Lua = opaque {
20482048 }
20492049 }
20502050
2051+ /// Used by C functions to validate received arguments.
2052+ /// If the function argument `arg_n` is a string, returns this string. If this argument is absent or is nil,
2053+ /// returns d. Otherwise, raises an error.
2054+ ///
2055+ /// From: `const char *luaL_optstring(lua_State *L, int narg, const char *d);`
2056+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_optstring
2057+ /// Stack Behavior: `[-0, +0, v]`
2058+ pub fn checkStringOptional (lua : * Lua , arg_n : i32 , d : [* :0 ]const u8 ) [* :0 ]const u8 {
2059+ const string : ? [* :0 ]const u8 = c .luaL_optlstring (asState (lua ), arg_n , d , null );
2060+ if (string ) | s | {
2061+ return s ;
2062+ } else {
2063+ unreachable ; // If the argument is not a string or convertable to a string, the argument check should fail and the call will not return.
2064+ }
2065+ }
2066+
20512067 /// Used by C functions to validate received arguments.
20522068 /// Checks whether the function argument `arg_n` is a string and returns this string.
20532069 /// All conversions and caveats of `lua.toLString()` also apply here.
@@ -2065,6 +2081,23 @@ pub const Lua = opaque {
20652081 }
20662082 }
20672083
2084+ /// Used by C functions to validate received arguments.
2085+ /// If the function argument "arg_n" is a string, returns this string. If this argument is absent or is nil,
2086+ /// returns d. Otherwise, raises an error.
2087+ ///
2088+ /// From: `const char *luaL_optlstring(lua_State *L, int narg, const char *d, size_t *l);`
2089+ /// Refer to: https://www.lua.org/manual/5.1/manual.html#luaL_optlstring
2090+ /// Stack Behavior: `[-0, +0, v]`
2091+ pub fn checkLStringOptional (lua : * Lua , arg_n : i32 , default : [:0 ]const u8 ) [:0 ]const u8 {
2092+ var len : usize = undefined ;
2093+ const string : ? [* ]const u8 = c .luaL_optlstring (asState (lua ), arg_n , default , & len );
2094+ if (string ) | s | {
2095+ return s [0.. len :0 ];
2096+ } else {
2097+ unreachable ; // If the argument is not a string or convertable to a string, the argument check should fail and the call will not return.
2098+ }
2099+ }
2100+
20682101 /// Used by C functions to validate received arguments.
20692102 /// Checks whether the function argument is a userdata of the specified type.
20702103 ///
@@ -3622,6 +3655,38 @@ test "checkString() should validate presence of arguments and return the correct
36223655 lua .pop (1 );
36233656}
36243657
3658+ test "checkStringOptional() should validate presence of arguments and return the correct value" {
3659+ const lua = try Lua .init (std .testing .allocator );
3660+ defer lua .deinit ();
3661+
3662+ const T = struct {
3663+ fn EchoString (l : * Lua ) callconv (.c ) i32 {
3664+ const actual = l .checkStringOptional (1 , "FOO" );
3665+ l .pushString (actual );
3666+ return 1 ;
3667+ }
3668+ };
3669+
3670+ const expected = "Who is John Galt?" ;
3671+ lua .pushCFunction (T .EchoString );
3672+ lua .pushString (expected );
3673+ try lua .protectedCall (1 , 1 , 0 );
3674+ const a1 = try lua .toLString (-1 );
3675+ try std .testing .expectEqualSlices (u8 , expected , a1 );
3676+ lua .pop (1 );
3677+
3678+ lua .pushCFunction (T .EchoString );
3679+ try lua .protectedCall (0 , 1 , 0 );
3680+ try std .testing .expectEqualSlices (u8 , "FOO" , (try lua .toString (-1 ))[0.. 3 :0 ]);
3681+
3682+ lua .pushCFunction (T .EchoString );
3683+ lua .pushInteger (42 );
3684+ try lua .protectedCall (1 , 1 , 0 );
3685+ const a3 = try lua .toLString (-1 );
3686+ try std .testing .expectEqualStrings ("42" , a3 );
3687+ lua .pop (1 );
3688+ }
3689+
36253690test "checkLString() should validate presence of arguments and return the correct value" {
36263691 const lua = try Lua .init (std .testing .allocator );
36273692 defer lua .deinit ();
@@ -3655,6 +3720,38 @@ test "checkLString() should validate presence of arguments and return the correc
36553720 lua .pop (1 );
36563721}
36573722
3723+ test "checkLStringOptional() should validate presence of arguments and return the correct value" {
3724+ const lua = try Lua .init (std .testing .allocator );
3725+ defer lua .deinit ();
3726+
3727+ const T = struct {
3728+ fn EchoString (l : * Lua ) callconv (.c ) i32 {
3729+ const actual = l .checkLStringOptional (1 , "FOO" );
3730+ l .pushLString (actual );
3731+ return 1 ;
3732+ }
3733+ };
3734+
3735+ const expected = "Who is John Galt?" ;
3736+ lua .pushCFunction (T .EchoString );
3737+ lua .pushLString (expected );
3738+ try lua .protectedCall (1 , 1 , 0 );
3739+ const a1 = try lua .toLString (-1 );
3740+ try std .testing .expectEqualSlices (u8 , expected , a1 );
3741+ lua .pop (1 );
3742+
3743+ lua .pushCFunction (T .EchoString );
3744+ try lua .protectedCall (0 , 1 , 0 );
3745+ try std .testing .expectEqualSlices (u8 , "FOO" , try lua .toLString (-1 ));
3746+
3747+ lua .pushCFunction (T .EchoString );
3748+ lua .pushInteger (42 );
3749+ try lua .protectedCall (1 , 1 , 0 );
3750+ const a3 = try lua .toLString (-1 );
3751+ try std .testing .expectEqualSlices (u8 , "42" , a3 );
3752+ lua .pop (1 );
3753+ }
3754+
36583755test "checkAny should validate presence of arguments" {
36593756 const lua = try Lua .init (std .testing .allocator );
36603757 defer lua .deinit ();
0 commit comments