// Package config provides configuration validation and management. package config import ( "fmt" "net" "os" ) // Validator is an interface for types that can validate themselves. type Validator interface { Validate() error } // ValidateConfig validates a configuration struct that implements the Validator interface. func ValidateConfig(v Validator) error { return v.Validate() } // ValidatePort checks if a port number is within the valid range (1-65535). func ValidatePort(port int) error { if port < 1 || port > 65535 { return fmt.Errorf("invalid port: %d (must be 1-65535)", port) } return nil } // ValidateDirectory checks if a path exists and is a directory. func ValidateDirectory(path string) error { if path == "" { return fmt.Errorf("path cannot be empty") } expanded := ExpandPath(path) info, err := os.Stat(expanded) if err != nil { if os.IsNotExist(err) { return fmt.Errorf("directory does not exist: %s", expanded) } return fmt.Errorf("cannot access directory %s: %w", expanded, err) } if !info.IsDir() { return fmt.Errorf("path is not a directory: %s", expanded) } return nil } // ValidateRedisAddr validates a Redis address in the format "host:port". func ValidateRedisAddr(addr string) error { host, port, err := net.SplitHostPort(addr) if err != nil { return fmt.Errorf("invalid redis address format: %w", err) } if host == "" { return fmt.Errorf("redis host cannot be empty") } var portInt int if _, err := fmt.Sscanf(port, "%d", &portInt); err != nil { return fmt.Errorf("invalid port number %q: %w", port, err) } return ValidatePort(portInt) }