What is this used for?

Basic Examples

These examples provide a clearer sense of what Calid does — from coercion and defaults to full schema validation and error handling.

Basic validation: age must be a positive integer

local schema = calid:number():int():positive()
 
print(schema:parse(10))
-- { success = true, data = 10 }
 
print(schema:parse(-5))
-- { success = false, error = { code = "positive", message = "Must be positive" } }

Coercion: input as a string, coerced into number

local coerced = calid:number():coerce()
 
print(coerced:parse("42"))
-- { success = true, data = 42 }
 
print(coerced:parse("abc"))
-- { success = false, error = { code = "type", message = "Expected number, received string" } }

Object schema with defaults and optional fields

local userSchema = calid:object({
    name  = calid:string():min(1),
    role  = calid:enum({ "user", "admin" }):default("user"),
    email = calid:string():email():optional()
})
 
print(userSchema:parse({ name = "Ana" }))
-- { success = true, data = { name = "Ana", role = "user" } }
 
print(userSchema:parse({}))
-- { success = false, error = { code = "required", message = "Required field is missing", path = "name" } }

Custom error messages

local pwdSchema = calid:string({
    required_error = "Password required",
    type_error = "Password must be a string"
}):min(6, { message = "Too short" })
 
print(pwdSchema:parse(nil))
-- { success = false, error = { code = "required", message = "Password required" } }
 
print(pwdSchema:parse("123"))
-- { success = false, error = { code = "min", message = "Too short" } }

Nested object with array validation

local postSchema = calid:object({
    title = calid:string():min(1),
    tags = calid:array(calid:string()):min(1),
    author = calid:object({
        id = calid:string():uuid(),
        name = calid:string():min(1)
    })
})
 
local validInput = {
    title = "My Post",
    tags = { "lua", "validation" },
    author = {
        id = "550e8400-e29b-41d4-a716-446655440000",
        name = "John"
    }
}
 
print(postSchema:parse(validInput))
--{
--    success = true,
--    data = {
--        title = "My Post",
--        tags = { "lua", "validation" },
--        author = {
--            id = "550e8400-e29b-41d4-a716-446655440000",
--            name = "John"
--        }
--    }
--}
 
local invalidInput = {
    title = "Lorem Ipsum",
    tags = { "foo", "bar" },
    author = {
        id = "123",
        name = "Jane"
    }
}
 
print(postSchema:parse(invalidInput))
--{
--    success = false,
--    error = {
--        code = "uuid",
--        message = "Invalid UUID format",
--        path = "author.id"
--    }
--}