package service import ( "encoding/json" "fmt" "os" "time" "dario.cat/mergo" ) type Duration struct { time.Duration } func (s Duration) MarshalJSON() ([]byte, error) { return json.Marshal(s.Duration.String()) } func (s *Duration) UnmarshalJSON(data []byte) error { var str string err := json.Unmarshal(data, &str) if err != nil { return err } v, err := time.ParseDuration(str) if err != nil { return err } *s = Duration{v} return nil } type Config struct { MaxInterval Duration `json:"max-interval,omitempty"` MinInterval Duration `json:"min-interval,omitempty"` Mirrors []*Mirror `json:"mirrors,omitempty"` } var DefaultConfig = Config{ MaxInterval: Duration{24 * time.Hour}, MinInterval: Duration{time.Hour}, } func (c *Config) Apply(arg Config) { err := mergo.Merge(c, &arg) if err != nil { panic(err) } } // ApplyFileConfig loads the configuration described by the given yaml file. func ApplyFileConfig(cfg *Config, filePath string) error { var ret Config f, err := os.Open(filePath) if os.IsNotExist(err) { return nil } else if err != nil { return err } defer f.Close() err = json.NewDecoder(f).Decode(&ret) if err != nil { return fmt.Errorf("loading configuration file: %w", err) } cfg.Apply(ret) return nil }