> ## Documentation Index
> Fetch the complete documentation index at: https://ziva.zeleza.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Обзор валидации

> Как работает система проверки ввода в Ziva

# Система валидации

Ziva выполняет проверку пользовательского ввода непосредственно в `InputTask`. Как только пользователь нажимает <kbd>Enter</kbd>, задача вызывает валидатор и, при необходимости, возвращает сообщение об ошибке прямо в интерфейс.

## Базовое использование

```go theme={null}
v := ziva.DefaultValidators

email := ziva.NewInputTask("Email", "Введите адрес:").
    WithInputType(ziva.InputTypeEmail).
    WithValidator(v.Email())
```

Если email некорректен, пользователь увидит подсказку и сможет исправить значение без выхода из очереди.

## Что такое валидатор

Валидатор — это значение с двумя методами:

```go theme={null}
type Validator interface {
    Validate(input string) error
    Description() string
}
```

Возвращаемая ошибка попадает в интерфейс, описание используется для пояснения требований. Вам не нужно импортировать интерфейс — достаточно объявить тип с такими методами.

## Подключение встроенных валидаторов

```go theme={null}
v := ziva.DefaultValidators

username := ziva.NewInputTask("Имя", "3-20 символов, латиница")
username.WithValidator(v.Username())

port := ziva.NewInputTask("Порт", "1..65535").
    WithInputType(ziva.InputTypeNumber).
    WithValidator(v.Port())
```

Список всех доступных проверок смотрите в разделе [Встроенные валидаторы](/ru/validation/built-in-validators).

## Опциональные поля

Если значение может быть пустым:

```go theme={null}
phone := ziva.NewInputTask("Телефон", "Необязательно")
phone.WithAllowEmpty(true)
phone.WithValidator(funcValidator)
```

Комбинируйте `WithAllowEmpty(true)` с валидатором, который корректно обрабатывает пустую строку (например, `OptionalEmail()`).

## Кастомные валидаторы

```go theme={null}
type evenNumber struct{}

func (evenNumber) Validate(input string) error {
    n, err := strconv.Atoi(strings.TrimSpace(input))
    if err != nil {
        return errors.New("введите целое число")
    }
    if n%2 != 0 {
        return errors.New("нужно чётное число")
    }
    return nil
}

func (evenNumber) Description() string {
    return "Чётное целое число"
}

code := ziva.NewInputTask("Чётный ID", "Введите значение:")
code.WithInputType(ziva.InputTypeNumber)
code.WithValidator(evenNumber{})
```

Таким образом можно описывать любую бизнес-логику: от проверки контрольных сумм до валидации с внешними сервисами.

## Несколько проверок подряд

Часто нужно объединять условия:

```go theme={null}
v := ziva.DefaultValidators

validationChain := []interface {
    Validate(string) error
    Description() string
}{
    v.Required(),
    v.MinLength(3),
    v.MaxLength(20),
    v.AlphaNumeric(),
}

validator := compositeValidator(validationChain)

login := ziva.NewInputTask("Логин", "3-20 латинских символов")
login.WithValidator(validator)
```

`compositeValidator` — удобная обёртка (см. пример в разделе встроенных валидаторов). Можно написать свою, чтобы красиво объединять сообщения об ошибках.

## Обработка результата после очереди

Даже если поле прошло валидацию, дополнительно проверяйте его после `queue.Run()` — особенно если требуется обращение к внешним сервисам или БД.

```go theme={null}
queue := ziva.NewQueue("Регистрация")
queue.AddTasks(login, email)
if err := queue.Run(); err != nil {
    return err
}

// Дополнительная проверка уникальности
if exists(login.GetValue()) {
    return fmt.Errorf("логин %q уже используется", login.GetValue())
}
```

## Лучшие практики

* Формулируйте сообщения об ошибке так, чтобы пользователь понимал, как исправить ввод.
* Для сложных правил описывайте требования через `Description()` — Ziva покажет их как подсказку.
* Комбинируйте InputTask с FuncTask, если нужно выполнить длительную проверку (например, запрос к API) и показать подробный результат.
* Учитывайте локаль: если используете числа, не забудьте обрезать пробелы и заменить запятые на точки (в случае необходимости — сделайте собственный валидатор).

Подробнее о создании собственных валидаторов — в разделе [Кастомные валидаторы](/ru/validation/custom-validators).
