## Домашнее задание №9 «Валидатор структур» Необходимо реализовать функцию: ```golang func Validate(v interface{}) error ``` Она должна валидировать публичные поля входной структуры на основе структурного тэга `validate`. Функция может возвращать - или программную ошибку, произошедшую во время валидации; - или `ValidationErrors` - ошибку, являющуюся слайсом структур, содержащих имя поля и ошибку его валидации. Таким образом, нужно накопить все ошибки валидации, а не прерывать валидацию на первой ошибке. Если у поля нет структурных тэгов или нет тэга `validate`, то функция игнорирует его. Типы полей, которые обязательно должны поддерживаться: - `int`, `[]int`; - `string`, `[]string`. _При желании можно дополнительно поддержать любые другие типы (на ваше усмотрение)._ Необходимо реализовать следующие валидаторы: - Для строк: * `len:32` - длина строки должна быть ровно 32 символа; * `regexp:\\d+` - согласно регулярному выражению строка должна состоять из цифр (`\\` - экранирование слэша); * `in:foo,bar` - строка должна входить в множество строк {"foo", "bar"}. - Для чисел: * `min:10` - число не может быть меньше 10; * `max:20` - число не может быть больше 20; * `in:256,1024` - число должно входить в множество чисел {256, 1024}; - Для слайсов валидируется каждый элемент слайса. _При желании можно дополнительно добавить парочку новых правил (на ваше усмотрение)._ Допускается комбинация валидаторов по логическому "И" с помощью `|`, например: * `min:0|max:10` - число должно находится в пределах [0, 10]; * `regexp:\\d+|len:20` - строка должна состоять из цифр и иметь длину 20. **(\*) Дополнительное задание: поддержка валидации вложенных по композиции структур.** ```golang type User struct { m Meta `validate:"nested"` } ``` ### Критерии оценки - Пайплайн зелёный - 3 балла - Добавлены юнит-тесты - до 4 баллов - Понятность и чистота кода - до 3 баллов - Дополнительное задание на баллы не влияет #### Зачёт от 7 баллов ### Подсказки - `reflect.StructTag` - `regexp.Compile` - `errors.Is` ### Частые ошибки - Отсутствует проверка на то, что входной `interface{}` - структура. - Нет разделения на программные ошибки (неверный тэг, регулярка и пр.) и ошибки валидации. - Ошибки валидации не вынесены в отдельные переменные и не завраплены. - Соответственно в тестах не используется `errors.Is` / `errors.As`.