// Package diagnostics provides bounded, safe text for deterministic D&D // decisions and warnings. package diagnostics import ( "fmt" "strconv" "strings" ) const ( MaxIssues = 20 MaxDisplayedRunes = 128 MaxMessageBytes = 4096 ) func Truncate(value string) string { runes := []rune(value) if len(runes) <= MaxDisplayedRunes { return value } return string(runes[:MaxDisplayedRunes-1]) + "…" } func Quote(value string) string { return strconv.Quote(Truncate(value)) } func Aggregate(prefix string, issues []string) string { displayed := make([]string, 0, min(len(issues), MaxIssues)) for len(displayed) < len(issues) && len(displayed) < MaxIssues { issue := Truncate(issues[len(displayed)]) candidate := aggregateMessage(prefix, append(displayed, issue), len(issues)-len(displayed)-1) if len([]byte(candidate)) > MaxMessageBytes { break } displayed = append(displayed, issue) } return aggregateMessage(prefix, displayed, len(issues)-len(displayed)) } func aggregateMessage(prefix string, issues []string, omitted int) string { message := prefix + ": " + strings.Join(issues, ", ") if omitted > 0 { message += fmt.Sprintf("; %d additional issue(s) omitted", omitted) } return message } func min(left, right int) int { if left < right { return left } return right }