## Домашнее задание №9 «Генератор валидаторов»

Необходимо реализовать тулзу для кодогенерации методов, валидирующих структуры.

Первым аргументом бинарь принимает путь к файлу, содержащему описание структур.

Пример вызова:
```bash
$ go-validate models/models.go
```

**models.go**:
```golang
package models

type User {
    Name string
    Age  int `validate:"min:18|max:50"`
}
```

Программа видит, что в структуре `User` есть поле `Age`, среди тэгов которого есть
тэг **validate** и генерирует код валидации в файл **models_validation_generated.go**
(где **models** - имя исходного файла без расширения) в том же пакете, что и исходный файл.

**models_validation_generated.go**:
```golang
// Code generated by cool go-validate tool; DO NOT EDIT.
package models

func (u User) Validate() ([]ValidationError, error) {
    ...
}
```
, где
- `[]ValidationError` - слайс структур, содержащих имя поля и ошибку его валидации;
- `err` - программная ошибка, произошедшая во время валидации.

---

Типы полей, которые обязательно должны поддерживаться:
- `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.

Для большего понимания см. тесты.

**(\*) Дополнительное задание: поддержка валидации вложенных по композиции структур.**

---

Структура проекта:
- `models` - минимальный тестовый набор структур. `test.sh` компилирует
вашу тулзу и ставит её в систему, затем с помощью `go generate` генерирует код валидаторов,
а затем запускает тесты в пакете `models`.
- `go-validate` - набор файлов (и тестов к ним), реализующих тулзу.

**Сгенерированный код следует закоммитить!** Но имейте в виду, что
`test.sh` генерирует его заного, чтобы протестировать данный процесс.

---

Так как тестирование будет использовать `go generate models/models.go`,
необходимо доработать этот файл так, чтобы данная команда вызывала
нашу тулзу.

---

Не забудьте добавить в сгенерированный файл [дисклеймер](https://github.com/golang/go/blob/master/src/cmd/go/internal/generate/generate.go#L59)!

### Критерии оценки
- Закоммичен сгенерированный код - 1 балл
- Пайплайн зелёный - 3 балла
- Добавлены новые юнит-тесты (доработаны имеющиеся) в `models` - до 2 баллов
- Добавлены юнит-тесты для тулзы в `govalidate` - до 2 баллов
- Понятность и чистота кода - до 2 баллов
- Дополнительное задание на баллы не влияет

#### Зачёт от 7 баллов

### Подсказки
- `$GOFILE`
- `text/template`
- `regexp.MustCompile`
- `parser.ParseFile`
- `*ast.GenDecl`, `*ast.StructType`
- `go/format`
