Dragonfly2
129 строк · 2.7 Кб
1/*
2* Copyright 2020 The Dragonfly Authors
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17package util18
19import (20"encoding/json"21"errors"22"fmt"23"time"24
25"github.com/docker/go-units"26"golang.org/x/time/rate"27"gopkg.in/yaml.v3"28)
29
30// RateLimit is a wrapper for rate.Limit, support json and yaml unmarshal function
31// yaml example 1:
32// rate_limit: 2097152 # 2MiB
33// yaml example 2:
34// rate_limit: 2MiB
35type RateLimit struct {36rate.Limit37}
38
39type Size = RateLimit40
41func (r *RateLimit) UnmarshalJSON(b []byte) error {42return r.unmarshal(json.Unmarshal, b)43}
44
45func (r *RateLimit) UnmarshalYAML(node *yaml.Node) error {46return r.unmarshal(yaml.Unmarshal, []byte(node.Value))47}
48
49func (r *RateLimit) unmarshal(unmarshal func(in []byte, out any) (err error), b []byte) error {50var v any51if err := unmarshal(b, &v); err != nil {52return err53}54switch value := v.(type) {55case float64:56r.Limit = rate.Limit(value)57return nil58case int:59r.Limit = rate.Limit(value)60return nil61case string:62limit, err := units.RAMInBytes(value)63if err != nil {64return fmt.Errorf("invalid rate limit: %w", err)65}66r.Limit = rate.Limit(limit)67return nil68default:69return errors.New("invalid rate limit")70}71}
72
73type Duration struct {74time.Duration75}
76
77func (d *Duration) UnmarshalJSON(b []byte) error {78var v any79if err := json.Unmarshal(b, &v); err != nil {80return err81}82return d.unmarshal(v)83}
84
85func (d *Duration) UnmarshalYAML(node *yaml.Node) error {86var v any87switch node.Kind {88case yaml.ScalarNode:89switch node.Tag {90case "!!int":91var i int92if err := node.Decode(&i); err != nil {93return err94}95v = i96case "!!str":97var i string98if err := node.Decode(&i); err != nil {99return err100}101v = i102default:103return errors.New("invalid duration")104}105default:106return errors.New("invalid duration")107}108return d.unmarshal(v)109}
110
111func (d *Duration) unmarshal(v any) error {112switch value := v.(type) {113case float64:114d.Duration = time.Duration(value)115return nil116case int:117d.Duration = time.Duration(value)118return nil119case string:120var err error121d.Duration, err = time.ParseDuration(value)122if err != nil {123return err124}125return nil126default:127return errors.New("invalid duration")128}129}
130