Перейти к основному содержанию

Демонстрация валидации

Разберём очереди, которые показывают всё богатство системы валидации Ziva: от встроенных правил до комбинированных цепочек и собственных проверок.

Очередь со всеми стандартными валидаторами

func ShowBuiltInValidators() {
    v := ziva.DefaultValidators

    tasks := []ziva.Task{
        ziva.NewInputTask("Имя", "Обязательное поле:").
            WithValidator(v.Required()),

        ziva.NewInputTask("Логин", "3-20 символов, латиница/цифры:").
            WithValidator(v.Username()),

        ziva.NewInputTask("Краткое описание", "Не более 40 символов:").
            WithValidator(v.MaxLength(40)),

        ziva.NewInputTask("Комментарий", "Минимум 5 символов:").
            WithValidator(v.MinLength(5)),

        ziva.NewInputTask("Код", "Ровно 8 символов:").
            WithValidator(v.Length(8)),

        ziva.NewInputTask("Email", "Адрес электронной почты:").
            WithInputType(ziva.InputTypeEmail).
            WithValidator(v.Email()),

        ziva.NewInputTask("Сайт", "URL (опционально):").
            WithValidator(v.OptionalURL()),

        ziva.NewInputTask("IP", "IPv4 или IPv6:").
            WithInputType(ziva.InputTypeIP).
            WithValidator(v.IP()),

        ziva.NewInputTask("Домен", "Имя домена:").
            WithInputType(ziva.InputTypeDomain).
            WithValidator(v.Domain()),

        ziva.NewInputTask("Порт", "Диапазон 1-65535:").
            WithInputType(ziva.InputTypeNumber).
            WithValidator(v.Port()),

        ziva.NewInputTask("Число", "Диапазон 1-100:").
            WithInputType(ziva.InputTypeNumber).
            WithValidator(v.Range(1, 100)),

        ziva.NewInputTask("Только буквы и цифры", "Введите значение:").
            WithValidator(v.AlphaNumeric()),

        ziva.NewInputTask("Пароль", "Минимум 8 символов:").
            WithInputType(ziva.InputTypePassword).
            WithValidator(v.StandardPassword()),

        ziva.NewInputTask("Сильный пароль", "Минимум 12 символов, разные символы:").
            WithInputType(ziva.InputTypePassword).
            WithValidator(v.StrongPassword()),
    }

    queue := ziva.NewQueue("Проверка валидаторов").
        WithTasksNumbered(true, "[%02d]")
    queue.AddTasks(tasks...)
    _ = queue.Run()
}
Каждая задача вызывает валидатор после нажатия Enter. При ошибке пользователь увидит сообщение и сможет вводить данные повторно, пока не выполнит условия.

Кастомная цепочка проверок

type Chain struct {
    validators []ziva.Validator
}

func (c Chain) Validate(input string) error {
    for _, validator := range c.validators {
        if err := validator.Validate(input); err != nil {
            return err
        }
    }
    return nil
}

func (c Chain) Description() string {
    parts := make([]string, len(c.validators))
    for i, validator := range c.validators {
        parts[i] = validator.Description()
    }
    return strings.Join(parts, "; ")
}

func AskSecureToken() {
    v := ziva.DefaultValidators

    token := ziva.NewInputTask(
        "API токен",
        "Обязательный, 16-64 символа, буквы/цифры",
    ).WithValidator(Chain{
        validators: []ziva.Validator{
            v.Required(),
            v.MinLength(16),
            v.MaxLength(64),
            v.AlphaNumeric(),
        },
    })

    queue := ziva.NewQueue("Проверка токена")
    queue.AddTasks(token)
    _ = queue.Run()

    fmt.Println("Токен принят:", token.GetValue())
}

Валидатор со сторонней проверкой

func emailNotInCRM(email string) bool {
    // Здесь могла бы быть реальная проверка API.
    return !strings.HasSuffix(email, "@banned.example")
}

type UniqueEmail struct{}

func (UniqueEmail) Validate(input string) error {
    if !emailNotInCRM(input) {
        return errors.New("email уже зарегистрирован")
    }
    return nil
}

func (UniqueEmail) Description() string {
    return "Email должен быть уникальным в CRM"
}

func SignUpForm() error {
    v := ziva.DefaultValidators

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

    password := ziva.NewInputTask(
        "Пароль",
        "Минимум 12 символов, буквы/цифры/символы",
    ).WithInputType(ziva.InputTypePassword).
        WithValidator(v.StrongPassword())

    confirm := ziva.NewYesNoTask(
        "Подтверждение",
        "Отправить данные в CRM?",
    ).WithDefaultYes()

    queue := ziva.NewQueue("Регистрация пользователя")
    queue.AddTasks(email, password, confirm)
    if err := queue.Run(); err != nil {
        return err
    }

    unique := ziva.NewInputTask("Проверка уникальности", "Email не должен быть в CRM:").
        WithInputType(ziva.InputTypeEmail).
        WithValidator(UniqueEmail{})

    checkQueue := ziva.NewQueue("Проверка CRM")
    checkQueue.AddTasks(unique)
    return checkQueue.Run()
}
Используйте FuncTask после ввода, если нужно выполнить длительную или сетевую проверку и показать итог пользователю.

Полезные советы

  • Сохраняйте Description() на понятном пользователю языке — Ziva выводит его рядом с полем.
  • Комбинируйте WithAllowEmpty(true) с валидаторами, которые корректно обрабатывают пустой ввод.
  • Для групповых форм разбивайте очередь на несколько смысловых блоков — так легче возвращаться к неправильному полю.
  • Покрывайте сложные валидаторы модульными тестами: они — обычные функции Go.
Следующая страница содержит совокупные рекомендации по использованию библиотеки Ziva в проектах.
I