mirror of
https://github.com/chenasraf/input-form.nvim.git
synced 2026-05-18 01:38:59 +00:00
feat: input validators
This commit is contained in:
139
lua/input-form/validators.lua
Normal file
139
lua/input-form/validators.lua
Normal file
@@ -0,0 +1,139 @@
|
||||
--- Validators for form inputs.
|
||||
---
|
||||
--- A validator is a function `fun(value): string|nil`. It receives the
|
||||
--- current input value and returns a non-empty error message string when
|
||||
--- invalid, or `nil` / `""` when valid.
|
||||
---
|
||||
--- This module exposes factory functions for common validators plus a
|
||||
--- `chain` combinator that runs several validators in order and returns the
|
||||
--- first error.
|
||||
---
|
||||
---@tag input-form.validators
|
||||
|
||||
local M = {}
|
||||
|
||||
--- Require the field to have a non-empty value.
|
||||
---@param msg string|nil Override error message.
|
||||
---@return function
|
||||
function M.non_empty(msg)
|
||||
msg = msg or "This field is required"
|
||||
return function(value)
|
||||
if value == nil then
|
||||
return msg
|
||||
end
|
||||
if type(value) == "string" and value == "" then
|
||||
return msg
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Require the value's length to be at least `n` characters.
|
||||
---@param n integer
|
||||
---@param msg string|nil
|
||||
---@return function
|
||||
function M.min_length(n, msg)
|
||||
return function(value)
|
||||
local s = type(value) == "string" and value or tostring(value or "")
|
||||
if vim.fn.strchars(s) < n then
|
||||
return msg or ("Must be at least " .. n .. " characters")
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Require the value's length to be at most `n` characters.
|
||||
---@param n integer
|
||||
---@param msg string|nil
|
||||
---@return function
|
||||
function M.max_length(n, msg)
|
||||
return function(value)
|
||||
local s = type(value) == "string" and value or tostring(value or "")
|
||||
if vim.fn.strchars(s) > n then
|
||||
return msg or ("Must be at most " .. n .. " characters")
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Require the value to match a Lua pattern.
|
||||
---@param pattern string Lua pattern (not PCRE).
|
||||
---@param msg string|nil
|
||||
---@return function
|
||||
function M.matches(pattern, msg)
|
||||
return function(value)
|
||||
local s = type(value) == "string" and value or tostring(value or "")
|
||||
if not s:match(pattern) then
|
||||
return msg or "Invalid format"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Require the value to parse as a number.
|
||||
---@param msg string|nil
|
||||
---@return function
|
||||
function M.is_number(msg)
|
||||
return function(value)
|
||||
if value == nil or value == "" or tonumber(value) == nil then
|
||||
return msg or "Must be a number"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Require the value to be one of the given choices (useful for text inputs
|
||||
--- that must match a fixed allowlist; select inputs should use their
|
||||
--- `options` list instead).
|
||||
---@param choices table List of allowed values.
|
||||
---@param msg string|nil
|
||||
---@return function
|
||||
function M.one_of(choices, msg)
|
||||
return function(value)
|
||||
for _, c in ipairs(choices) do
|
||||
if c == value then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
return msg or "Value is not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
--- Wrap a predicate `fun(value): boolean` as a validator.
|
||||
---@param predicate function
|
||||
---@param msg string Error message to return when the predicate is false.
|
||||
---@return function
|
||||
function M.custom(predicate, msg)
|
||||
return function(value)
|
||||
if predicate(value) then
|
||||
return nil
|
||||
end
|
||||
return msg
|
||||
end
|
||||
end
|
||||
|
||||
--- Combine multiple validators. Runs them in order and returns the first
|
||||
--- non-empty error. Accepts either a list table or a varargs list.
|
||||
---@param ... function|table
|
||||
---@return function
|
||||
function M.chain(...)
|
||||
local validators = { ... }
|
||||
if
|
||||
#validators == 1
|
||||
and type(validators[1]) == "table"
|
||||
and type(validators[1][1]) == "function"
|
||||
then
|
||||
validators = validators[1]
|
||||
end
|
||||
return function(value)
|
||||
for _, v in ipairs(validators) do
|
||||
local err = v(value)
|
||||
if err and err ~= "" then
|
||||
return err
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user