You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
1.8 KiB
Go

// Package valueobjects provides domain value objects for the KnowFoolery application.
package valueobjects
import (
"regexp"
"strings"
"knowfoolery/backend/shared/domain/errors"
)
const (
// MinPlayerNameLength is the minimum length of a player name.
MinPlayerNameLength = 2
// MaxPlayerNameLength is the maximum length of a player name.
MaxPlayerNameLength = 50
)
// playerNamePattern matches alphanumeric characters, spaces, hyphens, underscores, and dots.
var playerNamePattern = regexp.MustCompile(`^[a-zA-Z0-9\s\-_.]+$`)
// PlayerName represents a validated player name.
type PlayerName struct {
value string
}
// NewPlayerName creates a new PlayerName with validation.
func NewPlayerName(name string) (PlayerName, error) {
// Trim whitespace
name = strings.TrimSpace(name)
// Validate length
if len(name) < MinPlayerNameLength {
return PlayerName{}, errors.Wrap(
errors.CodeInvalidPlayerName,
"player name too short",
nil,
)
}
if len(name) > MaxPlayerNameLength {
return PlayerName{}, errors.Wrap(
errors.CodeInvalidPlayerName,
"player name too long",
nil,
)
}
// Validate characters
if !playerNamePattern.MatchString(name) {
return PlayerName{}, errors.Wrap(
errors.CodeInvalidPlayerName,
"player name contains invalid characters",
nil,
)
}
// Normalize multiple spaces to single space
spaceRegex := regexp.MustCompile(`\s+`)
name = spaceRegex.ReplaceAllString(name, " ")
return PlayerName{value: name}, nil
}
// String returns the string representation of the player name.
func (p PlayerName) String() string {
return p.value
}
// Equals checks if two player names are equal.
func (p PlayerName) Equals(other PlayerName) bool {
return strings.EqualFold(p.value, other.value)
}
// IsEmpty checks if the player name is empty.
func (p PlayerName) IsEmpty() bool {
return p.value == ""
}