{"id":20564442,"url":"https://github.com/tarantool/checks","last_synced_at":"2025-10-07T21:11:15.383Z","repository":{"id":29789337,"uuid":"122782022","full_name":"tarantool/checks","owner":"tarantool","description":"Easy, terse, readable and fast function arguments type checking","archived":false,"fork":false,"pushed_at":"2025-04-04T13:44:46.000Z","size":112,"stargazers_count":21,"open_issues_count":4,"forks_count":4,"subscribers_count":35,"default_branch":"master","last_synced_at":"2025-04-14T15:12:58.745Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tarantool.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-02-24T21:38:29.000Z","updated_at":"2025-04-04T13:44:48.000Z","dependencies_parsed_at":"2023-02-19T09:46:37.754Z","dependency_job_id":"87c86200-c30f-442f-a16a-69f8e29f1cf8","html_url":"https://github.com/tarantool/checks","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/tarantool/checks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fchecks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fchecks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fchecks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fchecks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tarantool","download_url":"https://codeload.github.com/tarantool/checks/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fchecks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278847704,"owners_count":26056356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T04:26:46.297Z","updated_at":"2025-10-07T21:11:15.340Z","avatar_url":"https://github.com/tarantool.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Test](https://github.com/tarantool/checks/actions/workflows/test.yml/badge.svg)](https://github.com/tarantool/checks/actions/workflows/test.yml)\n\n# Argument type checking API\n\nThis library declares a `checks()` function and a `checkers` table, which\nallow to check the parameters passed to a Lua function in a fast and\nunobtrusive way.\n\nStarting with 2.11.0, Tarantool embeds the `checks` module.\nYou can learn more about the module's API from the [documentation page](https://www.tarantool.io/doc/latest/reference/reference_lua/checks/).\n\n---\n\n**COGNIZE THE ESSENCE**\n\nIt is NOT designed to validate user input.\nIt is designed to provide better type checking of function arguments.\n\nIt is NOT designed to hide your problems.\nIt is designed to reveal mistakes in code.\n\nYou should think of `checks` as of `assert` on steroids.\n\n---\n\n## Description\n\nFunction `checks(type_1, ..., type_n)`,\nwhen called directly inside function `fn`,\nchecks that `fn`'s 1st argument conforms to `type_1`,\n2nd argument conforms to `type_2`, etc.\n\nType specifiers are strings or tables, and if the arguments passed\nto `fn` don't conform to their specification, a proper error message is produced,\npinpointing the call to `fn` as the faulty expression.\n\n## String type qualifiers\n\n### Lua type\n\nThe type is simply `type(arg)`, such as `'table'`, `'number'` etc.\n\n```lua\nfunction fn_string(x)\n    checks('string')\nend\nfn_string('foo') -- ok\nfn_string(99) -- error:  bad argument #1 to fn_string (string expected, got number)'\n```\n\n### Metatable type\n\nAn arbitrary name, which is stored in the `__type` field of the argument metatable\n\n```lua\nfunction fn_color(x)\n    checks('color')\nend\nlocal blue = setmetatable({0, 0, 255}, {__type = 'color'})\nfn_color(blue) -- ok\nfn_color({}) -- error: bad argument #1 to fn_color (color expected, got table)'\n```\n\n### A type-checking function name\n\nThe function would be stored in the `checkers` global table.\nThis function is called with original value passed to `fn`\nand must return `true` if the value is valid.\n\n```lua\nfunction fn_positive(x)\n    checks('positive')\nend\nfunction checkers.positive(p)\n  return (type(p) == 'number') and (p \u003e 0)\nend\nfn_positive(42) -- ok\nfn_positive(-1) -- error: bad argument #1 to fn_positive (positive expected, got number)'\n```\n\nOne can use built-in checkers:\n\n* `checks('uint64')`:\n\n  * Either integer lua number in range from `0` to `2^53-1` (inclusive)\n  * or lua cdata `ctype\u003cuint64_t\u003e`\n  * or lua cdata `ctype\u003cint64_t\u003e` in range from `0` to `LLONG_MAX`\n\n  After the check it is safe to call `ffi.cast('uint64_t', ...)`\n\n* `checks('int64')`:\n\n  * Either integer lua number in range from `-2^53+1` to `2^53-1` (inclusive)\n  * or lua cdata `ctype\u003cuint64_t\u003e` in range from `0` to `LLONG_MAX`\n  * or lua cdata `ctype\u003cint64_t\u003e`\n\n  After the check it is safe to call `ffi.cast('int64_t', ...)`\n\n* `checks('uuid')`:\n\n  * lua cdata `ctype\u003cstruct tt_uuid\u003e`\n    containing `uuid_object` from tarantool built-in\n    [module *uuid*](https://tarantool.io/en/doc/reference/reference_lua/uuid.html)\n\n* `checks('uuid_str')`:\n\n  * uuid as a 36-byte hexadecimal string\n\n  After the check it is safe to call `uuid.fromstr()`\n\n* `checks('uuid_bin')`:\n\n  * uuid as a 16-byte binary string\n\n  After the check it is safe to call `uuid.frombin()`\n\n* `checks('tuple')`:\n\n  * Check that specified value is tuple\n\n* `checks('decimal')`:\n\n  * Check that specified value is decimal\n\n  (Available since Tarantool 2.4)\n\n### Optional type and types combination\n\nMoreover, several types can be accepted\nif their names are concatenated with a bar `|` between them.\nFor instance, `'table|number'` accepts tables as well as numbers.\n\nFinally, string type qualifier can be prefixed\nwith a question mark `?`, which makes them optional.\nFor instance, `'?table'` accepts tables as well as `nil` values,\n`'?table|number'` accepts tables, numbers and nil values.\n\nQuestion mark is not an equivalent to combination with the `'nil'` type:\n`box.NULL` is a valid value for `'?number'`, but not for `'nil|number'` combination.\n\nA `'?'` type alone accepts anything. It is mainly useful as a placeholder\nto skip an argument which doesn't need to be checked.\n\nTo sum up, the string type qualifier has the following syntax:\neither `'[?]type1[|type2[...]]'` or single `'?'`.\n\n## Table type qualifiers\n\nThe type qualifier may be a table.\nIn this case the argument is checked to conform to `'?table'` type, and its content is validated.\nTable values are validated against type qualifiers as described above.\nTable keys, which are not mentioned in `checks`, are validated against `'nil'` type.\nTable type qualifiers may be recursive and use tables too.\n\n```lua\nfunction fn_opts(options)\n    checks({\n        my_string = '?string',\n        my_number = '?number',\n    })\nend\n\nfn_opts({my_string = 's'}) -- ok\nfn_opts({my_number = 101}) -- ok\nfn_opts({my_number = 'x'}) -- error: bad argument options.my_number to fn_opts (?number expected, got string)'\nfn_opts({bad_field = true}) -- error: unexpected argument options.bad_field to fn_opts\n```\n\nSince v3.0 `checks` does not modify any arguments. Be careful when indexing options table:\n\n```lua\nfunction fn_bad(options)\n    checks({timeout = '?number'})\n    print(options.timeout)\nend\n\nfn_bad() -- error: attempt to index local 'options' (a nil value)\n\n\nfunction fn_good(options)\n    checks({timeout = '?number'})\n    local timeout = options and options.timeout or default_value\n    print(timeout)\nend\n\nfn_good() -- ok, prints default_value\n```\n\nTo keep backward compatibility you can use the flag `_G._checks_v2_compatible = true`.\nThis will substitute `nil` arguments with an empty table (as it used to be in v2.1).\n\n```lua\n_G._checks_v2_compatible = true\nlocal checks = require('checks')\nlocal json = require('json')\n\nfunction fn_v2_compatible(options)\n    checks({timeout = '?number'})\n    print(options.timeout)\nend\n\nfn_v2_compatible() -- ok, prints \"nil\"\n```\n\nWhen an argument inside table type qualifier is specified without question mark\n(i.e. not optional), whole table becomes mandatory:\n\n```lua\nfunction fn(options)\n    checks({\n        req_string = 'string',\n    })\nend\n\nfn() -- error: bad argument options.req_string to fn (string expected, got nil)'\n```\n\n## Variable number of arguments\n\nFunctions with variable number of arguments are supported:\n\n```lua\nfunction fn_varargs(arg1, ...)\n    checks('string')\nend\n\nfn_varargs('s') -- ok\nfn_varargs('s', 1) -- ok\nfn_varargs('s', {}) -- ok\nfn_varargs(42) -- error: bad argument #1 to fn_varargs (string expected, got number)'\n```\n\n## Credits\n\nThis library was originally a part of\n[luasched](https://github.com/SierraWireless/luasched).\nNow it is a dependency for luacheck.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarantool%2Fchecks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftarantool%2Fchecks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarantool%2Fchecks/lists"}