-- Copyright 2020-2022 Mitchell. See LICENSE. --[[ This comment is for LuaDoc. --- -- Extends `_G` with formatted assertions and function argument type checks. module('assert')]] --- -- Asserts that value *v* is not `false` or `nil` and returns *v*, or calls `error()` with -- *message* as the error message, defaulting to "assertion failed!". -- If *message* is a format string, the remaining arguments are passed to `string.format()` -- and the resulting string becomes the error message. -- @param v Value to assert. -- @param message Optional error message to show on error. The default value is "assertion failed!". -- @param ... If *message* is a format string, these arguments are passed to `string.format()`. -- @name _G.assert function assert(v, message, ...) if v then return v end if type(message) == 'string' and message:find('%%') then message = string.format(message, ...) end error(message or 'assertion failed!', 2) end --- -- Asserts that value *v* has type string *expected_type* and returns *v*, or calls `error()` -- with an error message that implicates function argument number *narg*. -- This is intended to be used with API function arguments so users receive more helpful error -- messages. -- @param v Value to assert the type of. -- @param expected_type String type to assert. It may be a non-letter-delimited list of type -- options. -- @param narg The positional argument number *v* is associated with. This is not required to -- be a number. -- @usage assert_type(filename, 'string/nil', 1) -- @usage assert_type(option.setting, 'number', 'setting') -- implicates key -- @name _G.assert_type function assert_type(v, expected_type, narg) if type(v) == expected_type then return v end -- Note: do not use assert for performance reasons. if type(expected_type) ~= 'string' then error(string.format("bad argument #2 to '%s' (string expected, got %s)", debug.getinfo(1, 'n').name, type(expected_type)), 2) elseif narg == nil then error(string.format("bad argument #3 to '%s' (value expected, got %s)", debug.getinfo(1, 'n').name, type(narg)), 2) end for type_option in expected_type:gmatch('%a+') do if type(v) == type_option then return v end end error(string.format("bad argument #%s to '%s' (%s expected, got %s)", narg, debug.getinfo(2, 'n').name or '?', expected_type, type(v)), 3) end