Files
2026-10-04 04:07:49 +07:00

75 lines
2.6 KiB
Go

package team_service
import (
"bytes"
"encoding/json"
"errors"
"net/mail"
"strconv"
"strings"
"unicode/utf8"
)
var (
ErrInvalidCaptainEmail = errors.New("укажите корректную почту капитана")
ErrInvalidParticipantsCount = errors.New("укажите от 1 до 8 участников")
ErrTeamNotFound = errors.New("команда не найдена")
ErrInvalidRegistration = errors.New("укажите название команды (до 255 символов), почту капитана и положительное количество участников")
ErrRegistrationClosed = errors.New("игра не найдена или регистрация уже закрыта")
)
// Registration contains data required to register a team.
type Registration struct {
Name string `json:"name"`
Email string `json:"email"`
ParticipantsCount int32 `json:"participantsCount"`
}
// UnmarshalJSON decodes and normalizes registration data.
func (r *Registration) UnmarshalJSON(data []byte) error {
var payload struct {
Name string `json:"name"`
Email string `json:"email"`
ParticipantsCount json.RawMessage `json:"participantsCount"`
}
decoder := json.NewDecoder(bytes.NewReader(data))
decoder.DisallowUnknownFields()
if err := decoder.Decode(&payload); err != nil {
return err
}
r.Name = payload.Name
r.Email = payload.Email
if len(payload.ParticipantsCount) == 0 {
return nil
}
if err := json.Unmarshal(payload.ParticipantsCount, &r.ParticipantsCount); err == nil {
return nil
}
var value string
if err := json.Unmarshal(payload.ParticipantsCount, &value); err != nil {
return errors.New(`поле "participantsCount" должно быть целым числом или строкой с целым числом`)
}
count, err := strconv.ParseInt(value, 10, 32)
if err != nil {
return errors.New(`поле "participantsCount" должно быть целым числом или строкой с целым числом`)
}
r.ParticipantsCount = int32(count)
return nil
}
func validCaptainEmail(email string) bool {
address, err := mail.ParseAddress(email)
return err == nil && address.Address == email && len(email) <= 254
}
// Validate checks registration data.
func (r *Registration) Validate() error {
r.Name = strings.TrimSpace(r.Name)
r.Email = strings.TrimSpace(r.Email)
if r.Name == "" || !utf8.ValidString(r.Name) || strings.ContainsRune(r.Name, 0) || utf8.RuneCountInString(r.Name) > 255 ||
!validCaptainEmail(r.Email) || r.ParticipantsCount <= 0 {
return ErrInvalidRegistration
}
return nil
}