package ratelimit import ( "strconv" "strings" ) // trimSpaceAndLower normalisiert eine Eingabe für den Vergleich. // // Leerzeichen innerhalb der Angabe werden ebenfalls entfernt: „50 MB" ist die // natürliche Schreibweise und sollte nicht an einem Leerzeichen scheitern. func trimSpaceAndLower(inputText string) string { return strings.ToLower(strings.ReplaceAll(strings.TrimSpace(inputText), " ", "")) } // cutSuffix trennt eine bekannte Einheit ab. func cutSuffix(inputText string, unitSuffix string) (string, bool) { // Ein zusätzliches "/s" oder "ps" ist gebräuchlich und wird geduldet: // „50MB/s" meint dasselbe wie „50MB". for _, rateSuffix := range []string{"/s", "ps", ""} { fullSuffix := unitSuffix + rateSuffix if trimmedText, hasSuffix := strings.CutSuffix(inputText, fullSuffix); hasSuffix { return trimmedText, true } } return inputText, false } // parseFloatValue liest eine Zahl. // // Gebrochene Angaben sind zugelassen: „1.5MB" ist eine sinnvolle Grenze, und // sie abzulehnen zwänge zur Umrechnung in Byte. func parseFloatValue(numericText string) (float64, error) { trimmedText := strings.TrimSpace(numericText) // Das deutsche Dezimalkomma wird angenommen; wer „1,5MB" einträgt, meint // dasselbe wie „1.5MB". trimmedText = strings.Replace(trimmedText, ",", ".", 1) parsedValue, parseError := strconv.ParseFloat(trimmedText, 64) if parseError != nil { return 0, parseError } if parsedValue < 0 { return 0, strconv.ErrRange } return parsedValue, nil } // FormatBandwidthLimit gibt eine Rate lesbar aus. func FormatBandwidthLimit(bytesPerSecond int64) string { if bytesPerSecond <= Unlimited { return "unbegrenzt" } unitSuffixes := []struct { // suffix ist die Einheit. suffix string // threshold ist die Untergrenze ihrer Verwendung. threshold int64 }{ {"GB/s", 1 << 30}, {"MB/s", 1 << 20}, {"KB/s", 1 << 10}, } for _, unitSuffix := range unitSuffixes { if bytesPerSecond >= unitSuffix.threshold { return strconv.FormatFloat(float64(bytesPerSecond)/float64(unitSuffix.threshold), 'f', 1, 64) + " " + unitSuffix.suffix } } return strconv.FormatInt(bytesPerSecond, 10) + " B/s" }