66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
package conf
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const defaultOverTime = time.Hour
|
|
|
|
const (
|
|
BurstRateType = "burst"
|
|
IntervalRateType = "interval"
|
|
)
|
|
|
|
type Rate struct {
|
|
Events float64 `json:"events,omitempty"`
|
|
OverTime time.Duration `json:"over_time,omitempty"`
|
|
typ string
|
|
}
|
|
|
|
func (r *Rate) GetRateType() string {
|
|
if r.typ == "" {
|
|
return IntervalRateType
|
|
}
|
|
return r.typ
|
|
}
|
|
|
|
// Decode is used by envconfig to parse the env-config string to a Rate value.
|
|
func (r *Rate) Decode(value string) error {
|
|
if f, err := strconv.ParseFloat(value, 64); err == nil {
|
|
r.typ = IntervalRateType
|
|
r.Events = f
|
|
r.OverTime = defaultOverTime
|
|
return nil
|
|
}
|
|
parts := strings.Split(value, "/")
|
|
if len(parts) != 2 {
|
|
return fmt.Errorf("rate: value does not match rate syntax %q", value)
|
|
}
|
|
|
|
// 52 because the uint needs to fit in a float64
|
|
e, err := strconv.ParseUint(parts[0], 10, 52)
|
|
if err != nil {
|
|
return fmt.Errorf("rate: events part of rate value %q failed to parse as uint64: %w", value, err)
|
|
}
|
|
|
|
d, err := time.ParseDuration(parts[1])
|
|
if err != nil {
|
|
return fmt.Errorf("rate: over-time part of rate value %q failed to parse as duration: %w", value, err)
|
|
}
|
|
|
|
r.typ = BurstRateType
|
|
r.Events = float64(e)
|
|
r.OverTime = d
|
|
return nil
|
|
}
|
|
|
|
func (r *Rate) String() string {
|
|
if r.OverTime == 0 {
|
|
return fmt.Sprintf("%f", r.Events)
|
|
}
|
|
return fmt.Sprintf("%d/%s", uint64(r.Events), r.OverTime.String())
|
|
}
|