109 lines
2.2 KiB
Go
109 lines
2.2 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type ListeningMode int64
|
|
|
|
func (lm ListeningMode) String() string {
|
|
mapping := map[ListeningMode]string{
|
|
ModeNet: "net",
|
|
ModeUnix: "unix",
|
|
}
|
|
val := mapping[lm]
|
|
return val
|
|
}
|
|
|
|
func listeningModeFromString(rawVal string) (ListeningMode, error) {
|
|
mapping := map[string]ListeningMode{
|
|
"unix": ModeUnix,
|
|
"net": ModeNet,
|
|
}
|
|
if typedVal, ok := mapping[rawVal]; !ok {
|
|
return ModeNet, fmt.Errorf("invalid listening mode %s", rawVal)
|
|
} else {
|
|
return typedVal, nil
|
|
}
|
|
}
|
|
|
|
const (
|
|
ModeUnix ListeningMode = iota
|
|
ModeNet
|
|
)
|
|
|
|
type jsonConf struct {
|
|
Log struct {
|
|
Level string `json:"level"`
|
|
} `json:"log"`
|
|
Server struct {
|
|
Host string `json:"host"`
|
|
Port int `json:"port"`
|
|
Mode string `json:"mode"`
|
|
SockPath string `json:"sock"`
|
|
} `json:"server"`
|
|
}
|
|
|
|
type AppConfig struct {
|
|
LogLevel logrus.Level
|
|
ServerMode ListeningMode
|
|
Host string
|
|
Port int
|
|
SockPath string
|
|
}
|
|
|
|
func parseLevel(lvlStr string) logrus.Level {
|
|
for _, lvl := range logrus.AllLevels {
|
|
if lvl.String() == lvlStr {
|
|
return lvl
|
|
}
|
|
}
|
|
return logrus.InfoLevel
|
|
}
|
|
|
|
func (ac *AppConfig) UnmarshalJSON(data []byte) error {
|
|
var jsonConf jsonConf
|
|
if err := json.Unmarshal(data, &jsonConf); err != nil {
|
|
return fmt.Errorf("failed to read JSON: %w", err)
|
|
}
|
|
ac.LogLevel = parseLevel(jsonConf.Log.Level)
|
|
|
|
lm, err := listeningModeFromString(jsonConf.Server.Mode)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse server listening mode: %w", err)
|
|
}
|
|
ac.ServerMode = lm
|
|
ac.SockPath = jsonConf.Server.SockPath
|
|
ac.Host = jsonConf.Server.Host
|
|
ac.Port = jsonConf.Server.Port
|
|
return nil
|
|
}
|
|
|
|
var defaultConfig AppConfig = AppConfig{
|
|
LogLevel: logrus.InfoLevel,
|
|
ServerMode: ModeNet,
|
|
Host: "0.0.0.0",
|
|
Port: 5000,
|
|
}
|
|
|
|
func New(filepath string) (*AppConfig, error) {
|
|
content, err := os.ReadFile(filepath)
|
|
if err != nil {
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
conf := defaultConfig
|
|
return &conf, nil
|
|
}
|
|
return nil, fmt.Errorf("failed to read config file %q: %w", filepath, err)
|
|
}
|
|
var conf AppConfig
|
|
if err := json.Unmarshal(content, &conf); err != nil {
|
|
return nil, fmt.Errorf("failed to parse config file: %w", err)
|
|
}
|
|
return &conf, nil
|
|
}
|