401 lines
10 KiB
Lua
401 lines
10 KiB
Lua
--- Is expression library
|
|
-- @module Is
|
|
-- @usage
|
|
-- local Is = require('stdlib/utils/is')
|
|
-- Is.True(true)
|
|
-- Is.Not.True(false)
|
|
-- Is.Assert.True(true)
|
|
-- Is.Assert.Not.True(false)
|
|
|
|
--- Is Table
|
|
-- @section Table
|
|
|
|
--- Is the test true.
|
|
-- @table Is
|
|
-- @field Not Is the test not true.
|
|
-- @field Assert Assert that the test is true.
|
|
-- @field Assert.Not Assert that the test is not true.
|
|
|
|
--- Is Table Callers
|
|
-- @section Callers
|
|
|
|
--- Is the test truthy
|
|
-- @function Is
|
|
-- @tparam mixed var
|
|
-- @treturn boolean
|
|
local Is = {}
|
|
|
|
--- Is the test not truthy
|
|
-- @function Not
|
|
-- @tparam mixed var
|
|
-- @treturn boolean
|
|
Is.Not = {}
|
|
|
|
--- Assert that the test is Truthy
|
|
-- @function Assert
|
|
-- @tparam mixed var
|
|
-- @treturn boolean
|
|
Is.Assert = {}
|
|
|
|
--- Assert that the test is not Truthy
|
|
-- @function Assert.Not
|
|
-- @tparam mixed var
|
|
-- @treturn boolean
|
|
Is.Assert.Not = {}
|
|
|
|
--- Functions
|
|
-- @section Functions
|
|
|
|
local M = {}
|
|
|
|
local type = type
|
|
local floor = math.floor
|
|
local INF_POS = math.huge
|
|
local INF_NEG = -math.huge
|
|
|
|
--- Returns the var if the passed variable is a table.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Table(var)
|
|
return type(var) == 'table' and var
|
|
end
|
|
M.table = M.Table
|
|
|
|
--- Returns the var if the passed variable is a string.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.String(var)
|
|
return type(var) == 'string' and var
|
|
end
|
|
M.string = M.String
|
|
|
|
--- Returns the var if the passed variable is a number.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Number(var)
|
|
return type(var) == 'number' and var
|
|
end
|
|
M.number = M.Number
|
|
|
|
function M.Thread(var)
|
|
return type(var) == 'thread' and var
|
|
end
|
|
M.thread = M.Thread
|
|
|
|
function M.Userdata(var)
|
|
return type(var) == 'userdata' and var
|
|
end
|
|
M.userdata = M.Userdata
|
|
|
|
--- Returns true if the passed variable is nil.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean
|
|
function M.Nil(var)
|
|
return type(var) == 'nil'
|
|
end
|
|
M.is_nil = M.Nil
|
|
|
|
--- Returns true if the passed variable is a boolean.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean
|
|
function M.Boolean(var)
|
|
return type(var) == 'boolean'
|
|
end
|
|
M.boolean = M.boolean
|
|
|
|
--- Returns true if the passed variable is true
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean
|
|
function M.True(var)
|
|
return var == true
|
|
end
|
|
M.is_true = M.True
|
|
|
|
--- Returns the var if the passed variable is not nil or false.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Truthy(var)
|
|
return var or false
|
|
end
|
|
M.truthy = M.Truthy
|
|
|
|
--- Returns true if the passed variable is false.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean
|
|
function M.False(var)
|
|
return var == false
|
|
end
|
|
M.is_false = M.False
|
|
|
|
--- Returns true if the passed variable is false or nil.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean
|
|
function M.Falsy(var)
|
|
return not var
|
|
end
|
|
M.falsy = M.Falsy
|
|
|
|
--- Returns true if the passed variable is nil, an empty table, or an empty string.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean
|
|
function M.Empty(var)
|
|
if M.Table(var) then
|
|
return _G.table_size and _G.table_size(var) == 0 or next(var) == nil
|
|
elseif M.String(var) then
|
|
return #string == 0
|
|
end
|
|
return M.Nil(var)
|
|
end
|
|
M.empty = M.Empty
|
|
|
|
function M.None(var)
|
|
return M.Empty(var) or M.False(var) or var == 0 or var ~= var
|
|
end
|
|
M.none = M.None
|
|
|
|
|
|
--- Returns the passed var if it is a positive number.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Positive(var)
|
|
return M.Number(var) and var >= 0 and var
|
|
end
|
|
M.positive = M.Positive
|
|
|
|
--- Returns the passed var if it is a positive number.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Negative(var)
|
|
return M.Number(var) and var < 0 and var
|
|
end
|
|
M.negative = M.Negative
|
|
|
|
function M.NaN(arg)
|
|
return arg ~= arg
|
|
end
|
|
M.nan = M.NaN
|
|
|
|
function M.Finite(var)
|
|
return M.Number(var) and (var < INF_POS and var > INF_NEG) and var
|
|
end
|
|
M.finite = M.Finite
|
|
|
|
function M.Int(var)
|
|
return M.Finite(var) and rawequal(floor(var), var) and var
|
|
end
|
|
M.int = M.Int
|
|
|
|
function M.Int8(var)
|
|
return M.Int(var) and var >= -128 and var <= 127 and var
|
|
end
|
|
M.int8 = M.Int8
|
|
|
|
function M.Int16(var)
|
|
return M.Int(var) and var >= -32768 and var <= 32767 and var
|
|
end
|
|
M.int16 = M.Int16
|
|
|
|
function M.Int32(var)
|
|
return M.Int(var) and var >= -2147483648 and var <= 2147483647 and var
|
|
end
|
|
M.int32 = M.Int32
|
|
|
|
function M.Unsigned(var)
|
|
return Is.Number(var) and (var < INF_POS and var >= 0) and var
|
|
end
|
|
M.unsigned = M.Unsigned
|
|
|
|
function M.UInt(var)
|
|
return M.Unsigned(var) and rawequal(floor(var), var) and var
|
|
end
|
|
M.uint = M.UInt
|
|
|
|
function M.UInt8(var)
|
|
return M.UInt(var) and var <= 255 and var
|
|
end
|
|
M.uint8 = M.UInt8
|
|
|
|
function M.UInt16(var)
|
|
return M.UInt(var) and var <= 65535 and var
|
|
end
|
|
M.uint16 = M.UInt16
|
|
|
|
function M.UInt32(var)
|
|
return M.UInt(var) and var <= 4294967295 and var
|
|
end
|
|
M.uint32 = M.UInt32
|
|
|
|
--- Returns the passed var if it is a full position.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Position(var)
|
|
return M.Table(var) and (var.x and var.y) and var
|
|
end
|
|
M.position = M.Position
|
|
|
|
--- Returns the passed var if it is a full area.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Area(var)
|
|
return M.Table(var) and (M.Position(var.left_top) and M.Position(var.right_bottom)) and var
|
|
end
|
|
M.area = M.Area
|
|
|
|
--- Returns the passed var if it is a simple position/vector.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Vector(var)
|
|
return M.Table(var) and (M.Number(var[1]) and M.Number(var[2])) and var
|
|
end
|
|
M.vector = M.Vector
|
|
|
|
--- Returns the passed var if it is a simple area/boundingbox.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.BoundingBox(var)
|
|
return M.Table(var) and (M.Vector(var[1]) and M.Vector(var[2]))
|
|
end
|
|
M.boundingbox = M.BoundingBox
|
|
M.bounding_box = M.BoundingBox
|
|
M.Bounding_Box = M.BoundingBox
|
|
|
|
--- Returns the hex value of the passed var if it is hexadecimal.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn mixed
|
|
function M.Hex(var)
|
|
return M.String(var) and var:match('%x%x%x%x%x%x$')
|
|
end
|
|
M.hex = M.Hex
|
|
|
|
--- Returns true if the passed variable is a single alphbetical word.
|
|
-- Does not allow any special chars
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean true if the passed variable is a single alphbetical word
|
|
function M.StrictWord(var)
|
|
return M.String(var) and var:find('^[%a]+$') == 1
|
|
end
|
|
M.strict_word = M.StrictWord
|
|
|
|
--- Returns true if the passed variable is a single alphbetical word.
|
|
-- Allows _ and - as part of the word
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean true if the passed variable is a single alphbetical word
|
|
function M.AlphabetWord(var)
|
|
return M.String(var) and var:find('^[%a%_%-]+$') == 1
|
|
end
|
|
M.Word = M.AlphabetWord
|
|
|
|
--- Returns true if the passed variable is a single alphbetical word.
|
|
-- Must start with a letter, allows _ and - as part of the word
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean true if the passed variable is a single alphbetical word
|
|
function M.AlphanumWord(var)
|
|
return M.String(var) and var:find('^%a+[%w%_%-]*$') == 1
|
|
end
|
|
M.Alpha = M.AlphanumWord
|
|
M.alpha = M.AlphanumWord
|
|
M.alphanumword = M.AlphanumWord
|
|
|
|
--- Is this factorio object valid
|
|
-- @tparam LuaObject var The variable to check
|
|
-- @treturn boolean true if this is a valid LuaObject
|
|
function M.Valid(var)
|
|
return M.Table(var) and var.valid
|
|
end
|
|
M.valid = M.Valid
|
|
|
|
--- Is this a factorio object
|
|
-- @tparam LuaObject var The variable to check
|
|
-- @treturn boolean true if this is an LuaObject
|
|
function M.Object(var)
|
|
return M.Table(var) and var.__self
|
|
end
|
|
M.object = M.Object
|
|
|
|
--- Returns true if the passed variable is a callable function.
|
|
-- @tparam mixed var The variable to check
|
|
-- @treturn boolean true if the passed variable is a callable function
|
|
function M.Callable(var)
|
|
return type(var) == 'function' or type((getmetatable(var) or {}).__call) == 'function'
|
|
end
|
|
M.callable = M.Callable
|
|
M.Function = M.Callable
|
|
M.is_function = M.Callable
|
|
|
|
setmetatable(
|
|
Is,
|
|
{
|
|
__index = function(_, k)
|
|
return M[k] and function(_assert)
|
|
return M[k](_assert)
|
|
end or nil
|
|
end,
|
|
__call = function(_, ...)
|
|
return (...)
|
|
end
|
|
}
|
|
)
|
|
|
|
setmetatable(
|
|
Is.Not,
|
|
{
|
|
__index = function(_, k)
|
|
return M[k] and function(_assert)
|
|
return not M[k](_assert)
|
|
end or nil
|
|
end,
|
|
__call = function(_, ...)
|
|
return not (...)
|
|
end
|
|
}
|
|
)
|
|
|
|
-- convenience function for un-lambda-ing deferred error messages
|
|
local function safeinvoke(f)
|
|
local ok, msg = xpcall(f, debug.traceback)
|
|
if not ok then
|
|
-- ensure msg really is a string so there is theoretically no chance
|
|
-- of a triple fault (i.e.: from a monkey-patched debug.traceback
|
|
-- returning something that now fails to concatenate to a string)
|
|
if type(msg) == 'string' then
|
|
msg = '<<< DOUBLE FAULT: ' .. msg .. ' >>>'
|
|
end
|
|
end
|
|
-- for sanity-preservation, always return something truthy
|
|
return msg or 'Unknown Error'
|
|
end
|
|
|
|
setmetatable(
|
|
Is.Assert,
|
|
{
|
|
__index = function(_, k)
|
|
return M[k] and function(_assert, _message, _level)
|
|
_level = tonumber(_level) or 3
|
|
return M[k](_assert) or error(type(_message) == 'function' and safeinvoke(_message) or _message, _level)
|
|
end or nil
|
|
end,
|
|
__call = function(_, ...)
|
|
local param = {...}
|
|
return param[1] or error(type(param[2]) == 'function' and safeinvoke(param[2]) or param[2], tonumber(param[3]) or 3)
|
|
end
|
|
}
|
|
)
|
|
|
|
setmetatable(
|
|
Is.Assert.Not,
|
|
{
|
|
__index = function(_, k)
|
|
return M[k] and function(_assert, _message, _level)
|
|
_level = tonumber(_level) or 3
|
|
return not M[k](_assert) or error(type(_message) == 'function' and safeinvoke(_message) or _message, _level)
|
|
end or nil
|
|
end,
|
|
__call = function(_, ...)
|
|
local param = {...}
|
|
return not param[1] or error(type(param[2]) == 'function' and safeinvoke(param[2]) or param[2], tonumber(param[3]) or 3)
|
|
end
|
|
}
|
|
)
|
|
|
|
return Is
|