Module checks
Since: 2.11.0
The checks
module provides the ability to check the types of arguments passed to a Lua function.
You need to call the checks(type_1, …) function inside the target Lua function and pass one or more type qualifiers to check the corresponding argument types.
There are two types of type qualifiers:
- A string type qualifier checks whether a function’s argument conforms to the specified type. Example:
'string'
. - A table type qualifier checks whether the values of a table passed as an argument conform to the specified types. Example:
{ 'string', 'number' }
.
Note
For earlier versions, you can install the checks
module from the Tarantool rocks repository.
In Tarantool 2.11.0 and later versions, the checks API is available in a script without loading the module.
For earlier versions, you need to install the checks
module from the Tarantool rocks repository and load the module using the require()
directive:
local checks = require('checks')
For each argument to check, you need to specify its own type qualifier in the checks(type_1, …) function.
In the example below, the checks
function accepts a string
type qualifier to verify that only a string value can be passed to the greet
function.
Otherwise, an error is raised.
function greet(name)
checks('string')
return 'Hello, ' .. name
end
--[[
greet('John')
-- returns 'Hello, John'
greet(123)
-- raises an error: bad argument #1 to nil (string expected, got number)
--]]
To check the types of several arguments, you need to pass the corresponding type qualifiers to the checks
function.
In the example below, both arguments should be string values.
function greet_fullname(firstname, lastname)
checks('string', 'string')
return 'Hello, ' .. firstname .. ' ' .. lastname
end
--[[
greet_fullname('John', 'Smith')
-- returns 'Hello, John Smith'
greet_fullname('John', 1)
-- raises an error: bad argument #2 to nil (string expected, got number)
--]]
To skip checking specific arguments, use the ? placeholder.
You can check the types of explicitly specified arguments for functions that accept a variable number of arguments.
function extra_arguments_num(a, b, ...)
checks('string', 'number')
return select('#', ...)
end
--[[
extra_arguments_num('a', 2, 'c')
-- returns 1
extra_arguments_num('a', 'b', 'c')
-- raises an error: bad argument #1 to nil (string expected, got number)
--]]
This section describes how to check a specific argument type using a string type qualifier:
- The Supported types section describes all the types supported by the
checks
module. - If required, you can make a union type to allow an argument to accept several types.
- You can make any of the supported types optional.
- To skip checking specific arguments, use the ? placeholder.
A string type qualifier can accept any of the Lua types, for example, string
, number
, table
, or nil
.
In the example below, the checks
function accepts string
to validate that only a string value can be passed to the greet
function.
function greet(name)
checks('string')
return 'Hello, ' .. name
end
--[[
greet('John')
-- returns 'Hello, John'
greet(123)
-- raises an error: bad argument #1 to nil (string expected, got number)
--]]
You can use Tarantool-specific types in a string qualifier. The example below shows how to check that a function argument is a decimal value.
local decimal = require('decimal')
function sqrt(value)
checks('decimal')
return decimal.sqrt(value)
end
--[[
sqrt(decimal.new(16))
-- returns 4
sqrt(16)
-- raises an error: bad argument #1 to nil (decimal expected, got number)
--]]
This table lists all the checks available for Tarantool types:
Check | Description | See also |
---|---|---|
checks('datetime') |
Check whether the specified value is datetime_object | checkers.datetime(value) |
checks('decimal') |
Check whether the specified value has the decimal type | checkers.decimal(value) |
checks('error') |
Check whether the specified value is error_object | checkers.error(value) |
checks('int64') |
Check whether the specified value is an int64 value |
checkers.int64(value) |
checks('interval') |
Check whether the specified value is interval_object | checkers.interval(value) |
checks('tuple') |
Check whether the specified value is a tuple | checkers.tuple(value) |
checks('uint64') |
Check whether the specified value is a uint64 value |
checkers.uint64(value) |
checks('uuid') |
Check whether the specified value is uuid_object | checkers.uuid(value) |
checks('uuid_bin') |
Check whether the specified value is uuid represented by a 16-byte binary string | checkers.uuid_bin(value) |
checks('uuid_str') |
Check whether the specified value is uuid represented by a 36-byte hexadecimal string | checkers.uuid_str(value) |
A string type qualifier can accept the name of a custom function that performs arbitrary validations.
To achieve this, create a function returning true
if the value is valid and add this function to the checkers table.
The example below shows how to use the positive
function to check that an argument value is a positive number.
function checkers.positive(value)
return (type(value) == 'number') and (value > 0)
end
function get_doubled_number(value)
checks('positive')
return value * 2
end
--[[
get_doubled_number(10)
-- returns 20
get_doubled_number(-5)
-- raises an error: bad argument #1 to nil (positive expected, got number)
--]]
A string qualifier can accept a value stored in the __type
field of the argument metatable.
local blue = setmetatable({ 0, 0, 255 }, { __type = 'color' })
function get_blue_value(color)
checks('color')
return color[3]
end
--[[
get_blue_value(blue)
-- returns 255
get_blue_value({0, 0, 255})
-- raises an error: bad argument #1 to nil (color expected, got table)
--]]
To allow an argument to accept several types (a union type), concatenate type names with a pipe (|
).
In the example below, the argument can be both a number
and string
value.
function get_argument_type(value)
checks('number|string')
return type(value)
end
--[[
get_argument_type(1)
-- returns 'number'
get_argument_type('key1')
-- returns 'string'
get_argument_type(true)
-- raises an error: bad argument #1 to nil (number|string expected, got boolean)
--]]
To make any of the supported types optional, prefix its name with a question mark (?
).
In the example below, the name
argument is optional.
This means that the greet
function can accept string
and nil
values.
function greet(name)
checks('?string')
if name ~= nil then
return 'Hello, ' .. name
else
return 'Hello from Tarantool'
end
end
--[[
greet('John')
-- returns 'Hello, John'
greet()
-- returns 'Hello from Tarantool'
greet(123)
-- raises an error: bad argument #1 to nil (string expected, got number)
--]]
As for a specific type, you can make a union type value optional: ?number|string
.
You can skip checking of the specified arguments using the question mark (?
) placeholder.
In this case, the argument can be any type.
function greet_fullname_any(firstname, lastname)
checks('string', '?')
return 'Hello, ' .. firstname .. ' ' .. tostring(lastname)
end
--[[
greet_fullname_any('John', 'Doe')
-- returns 'Hello, John Doe'
greet_fullname_any('John', 1)
-- returns 'Hello, John 1'
--]]
A table type qualifier checks whether the values of a table passed as an argument conform to the specified types. In this case, the following checks are made:
- The argument is checked to conform to the
?table
type, and its content is validated. - Table values are validated against the specified string type qualifiers.
- Table keys missing in
checks
are validated against thenil
type.
The code below checks that the first and second table values have the string
and number
types.
function configure_connection(options)
checks({ 'string', 'number' })
local ip_address = options[1] or '127.0.0.1'
local port = options[2] or 3301
return ip_address .. ':' .. port
end
--[[
configure_connection({'0.0.0.0', 3303})
-- returns '0.0.0.0:3303'
configure_connection({'0.0.0.0', '3303'})
-- raises an error: bad argument options[2] to nil (number expected, got string)
--]]
In the next example, the same checks are made for the specified keys.
function configure_connection_opts(options)
checks({ ip_address = 'string', port = 'number' })
local ip_address = options.ip_address or '127.0.0.1'
local port = options.port or 3301
return ip_address .. ':' .. port
end
--[[
configure_connection_opts({ip_address = '0.0.0.0', port = 3303})
-- returns '0.0.0.0:3303'
configure_connection_opts({ip_address = '0.0.0.0', port = '3303'})
-- raises an error: bad argument options.port to nil (number expected, got string)
configure_connection_opts({login = 'testuser', ip_address = '0.0.0.0', port = 3303})
-- raises an error: unexpected argument options.login to nil
--]]
Note
Table qualifiers can be nested and use tables, too.
Members | |
checks() | When called inside a function, checks that the function’s arguments conform to the specified types |
checkers | A global variable that provides access to checkers for different types |
-
checks
(type_1, ...)¶ When called inside a function, checks that the function’s arguments conform to the specified types.
Parameters: - type_1 (
string/table
) – a string or table type qualifier used to check the argument type - ... – optional type qualifiers used to check the types of other arguments
- type_1 (
The checkers
global variable provides access to checkers for different types.
You can use this variable to add a custom checker that performs arbitrary validations.
Note
The checkers
variable also provides access to checkers for Tarantool-specific types.
These checkers can be used in a custom checker.
-
checkers.
datetime
(value)¶ Check whether the specified value is datetime_object.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value isdatetime_object
; otherwise,false
Rtype: boolean
Example
local datetime = require('datetime') local is_datetime = checkers.datetime(datetime.new { day = 1, month = 6, year = 2023 }) local is_interval = checkers.interval(datetime.interval.new { day = 1 })
- value (
-
checkers.
decimal
(value)¶ Check whether the specified value has the decimal type.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value has thedecimal
type; otherwise,false
Rtype: boolean
Example
local decimal = require('decimal') local is_decimal = checkers.decimal(decimal.new(16))
- value (
-
checkers.
error
(value)¶ Check whether the specified value is error_object.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value iserror_object
; otherwise,false
Rtype: boolean
Example
local server_error = box.error.new({ code = 500, reason = 'Server error' }) local is_error = checkers.error(server_error)
- value (
-
checkers.
int64
(value)¶ Check whether the specified value is one of the following
int64
values:- a Lua number in a range from -2^53+1 to 2^53-1 (inclusive)
- Lua cdata
ctype<uint64_t>
in a range from 0 toLLONG_MAX
- Lua cdata
ctype<int64_t>
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value is anint64
value; otherwise,false
Rtype: boolean
Example
local is_int64 = checkers.int64(-1024) local is_uint64 = checkers.uint64(2048)
-
checkers.
interval
(value)¶ Check whether the specified value is interval_object.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value isinterval_object
; otherwise,false
Rtype: boolean
Example
local datetime = require('datetime') local is_datetime = checkers.datetime(datetime.new { day = 1, month = 6, year = 2023 }) local is_interval = checkers.interval(datetime.interval.new { day = 1 })
- value (
-
checkers.
tuple
(value)¶ Check whether the specified value is a tuple.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value is a tuple; otherwise,false
Rtype: boolean
Example
local is_tuple = checkers.tuple(box.tuple.new{1, 'The Beatles', 1960})
- value (
-
checkers.
uint64
(value)¶ Check whether the specified value is one of the following
uint64
values:- a Lua number in a range from 0 to 2^53-1 (inclusive)
- Lua cdata
ctype<uint64_t>
- Lua cdata
ctype<int64_t>
in range from 0 toLLONG_MAX
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value is anuint64
value; otherwise,false
Rtype: boolean
Example
local is_int64 = checkers.int64(-1024) local is_uint64 = checkers.uint64(2048)
-
checkers.
uuid
(value)¶ Check whether the specified value is uuid_object.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value isuuid_object
; otherwise,false
Rtype: boolean
Example
local uuid = require('uuid') local is_uuid = checkers.uuid(uuid()) local is_uuid_bin = checkers.uuid_bin(uuid.bin()) local is_uuid_str = checkers.uuid_str(uuid.str())
- value (
-
checkers.
uuid_bin
(value)¶ Check whether the specified value is uuid represented by a 16-byte binary string.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value isuuid
represented by a 16-byte binary string; otherwise,false
Rtype: boolean
See also: uuid(value)
- value (
-
checkers.
uuid_str
(value)¶ Check whether the specified value is uuid represented by a 36-byte hexadecimal string.
Parameters: - value (
any
) – the value to check the type for
Return: true
if the specified value isuuid
represented by a 36-byte hexadecimal string; otherwise,false
Rtype: boolean
See also: uuid(value)
- value (