Add projects
This commit is contained in:
parent
2d3a9ad623
commit
8b607dd700
1802 changed files with 503346 additions and 2 deletions
100
backend/internal/credentialweight/weight.go
Normal file
100
backend/internal/credentialweight/weight.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// Package credentialweight defines shared credential weight validation and parsing.
|
||||
package credentialweight
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// Default is used when a credential does not define a weight.
|
||||
Default int64 = 1
|
||||
// Max bounds scheduler arithmetic while allowing practical proportional routing.
|
||||
Max int64 = 1_000_000
|
||||
)
|
||||
|
||||
// Normalize validates and normalizes an explicit weight. Non-positive values are
|
||||
// valid and normalize to zero, which excludes the credential from weighted routing.
|
||||
func Normalize(weight int64) (int64, error) {
|
||||
if weight <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if weight > Max {
|
||||
return 0, fmt.Errorf("weight must not exceed %d", Max)
|
||||
}
|
||||
return weight, nil
|
||||
}
|
||||
|
||||
// ParseString parses a scheduler attribute. An empty value uses the default weight.
|
||||
func ParseString(raw string) (int64, error) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return Default, nil
|
||||
}
|
||||
weight, errParse := strconv.ParseInt(raw, 10, 64)
|
||||
if errParse != nil {
|
||||
return 0, fmt.Errorf("weight must be an integer: %w", errParse)
|
||||
}
|
||||
return Normalize(weight)
|
||||
}
|
||||
|
||||
// ParseValue parses a JSON-compatible auth-file metadata value.
|
||||
func ParseValue(value any) (int64, error) {
|
||||
switch typed := value.(type) {
|
||||
case int:
|
||||
return Normalize(int64(typed))
|
||||
case int8:
|
||||
return Normalize(int64(typed))
|
||||
case int16:
|
||||
return Normalize(int64(typed))
|
||||
case int32:
|
||||
return Normalize(int64(typed))
|
||||
case int64:
|
||||
return Normalize(typed)
|
||||
case uint:
|
||||
if uint64(typed) > uint64(Max) {
|
||||
return 0, fmt.Errorf("weight must not exceed %d", Max)
|
||||
}
|
||||
return int64(typed), nil
|
||||
case uint8:
|
||||
return int64(typed), nil
|
||||
case uint16:
|
||||
return int64(typed), nil
|
||||
case uint32:
|
||||
if uint64(typed) > uint64(Max) {
|
||||
return 0, fmt.Errorf("weight must not exceed %d", Max)
|
||||
}
|
||||
return int64(typed), nil
|
||||
case uint64:
|
||||
if typed > uint64(Max) {
|
||||
return 0, fmt.Errorf("weight must not exceed %d", Max)
|
||||
}
|
||||
return int64(typed), nil
|
||||
case float64:
|
||||
if math.IsNaN(typed) || math.IsInf(typed, 0) || math.Trunc(typed) != typed {
|
||||
return 0, fmt.Errorf("weight must be an integer")
|
||||
}
|
||||
if typed <= 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if typed > float64(Max) {
|
||||
return 0, fmt.Errorf("weight must not exceed %d", Max)
|
||||
}
|
||||
return int64(typed), nil
|
||||
case float32:
|
||||
return ParseValue(float64(typed))
|
||||
case json.Number:
|
||||
weight, errParse := typed.Int64()
|
||||
if errParse != nil {
|
||||
return 0, fmt.Errorf("weight must be an integer: %w", errParse)
|
||||
}
|
||||
return Normalize(weight)
|
||||
case string:
|
||||
return ParseString(typed)
|
||||
default:
|
||||
return 0, fmt.Errorf("weight must be an integer")
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue