2026-04-04 15:26:26 +08:00

76 lines
1.8 KiB
Go

package config
import (
"bytes"
"fmt"
"net"
"os"
"time"
"gopkg.in/yaml.v3"
)
const DefaultPath = "config/local.yaml"
// Config 汇总支付服务的运行配置。
type Config struct {
App AppConfig `yaml:"app"`
}
// AppConfig 描述支付服务自身监听参数。
type AppConfig struct {
Name string `yaml:"name"`
Env string `yaml:"env"`
HTTPAddr string `yaml:"http_addr"`
GRPCAddr string `yaml:"grpc_addr"`
ShutdownTimeout time.Duration `yaml:"shutdown_timeout"`
}
// Load 从 YAML 文件加载配置并校验。
func Load(path string) (Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return Config{}, fmt.Errorf("read config file %s: %w", path, err)
}
cfg := defaultConfig()
decoder := yaml.NewDecoder(bytes.NewReader(data))
decoder.KnownFields(true)
if err := decoder.Decode(&cfg); err != nil {
return Config{}, fmt.Errorf("decode config file %s: %w", path, err)
}
if err := validate(cfg); err != nil {
return Config{}, err
}
return cfg, nil
}
func defaultConfig() Config {
return Config{
App: AppConfig{
Name: "chatapppay",
Env: "local",
HTTPAddr: ":8082",
GRPCAddr: ":9002",
ShutdownTimeout: 10 * time.Second,
},
}
}
func validate(cfg Config) error {
if cfg.App.Name == "" {
return fmt.Errorf("app.name is required")
}
if _, err := net.ResolveTCPAddr("tcp", cfg.App.HTTPAddr); err != nil {
return fmt.Errorf("app.http_addr is invalid: %w", err)
}
if _, err := net.ResolveTCPAddr("tcp", cfg.App.GRPCAddr); err != nil {
return fmt.Errorf("app.grpc_addr is invalid: %w", err)
}
if cfg.App.ShutdownTimeout <= 0 {
return fmt.Errorf("app.shutdown_timeout must be greater than 0")
}
return nil
}