66 lines
3.8 KiB
Markdown
66 lines
3.8 KiB
Markdown
|
## Домашнее задание №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`.
|