62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
package configuration
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"errors"
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
)
|
||
|
|
|
||
|
|
var errCfg = errors.New("configuration")
|
||
|
|
|
||
|
|
// Config is a configuration controlling structure.
|
||
|
|
type Config struct {
|
||
|
|
RSS *RSS `json:"rss"`
|
||
|
|
Outputs *Outputs `json:"outputs"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// New creates new configuration controller.
|
||
|
|
func New(path string) (*Config, error) {
|
||
|
|
cfg := &Config{}
|
||
|
|
|
||
|
|
// Get configuration file real path.
|
||
|
|
userHomeDir, err := os.UserHomeDir()
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("%w: parse configuration file: get real path: get user home dir: %w", errCfg, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
path = strings.Replace(path, "~", userHomeDir, 1)
|
||
|
|
|
||
|
|
absPath, err := filepath.Abs(path)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("%w: parse configuration file: get real path: get absolute path: %w", errCfg, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
cfgFileData, err := os.ReadFile(absPath)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("%w: parse configuration file: read file: %w", errCfg, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := json.Unmarshal(cfgFileData, cfg); err != nil {
|
||
|
|
return nil, fmt.Errorf("%w: parse configuration file: %w", errCfg, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate configuration.
|
||
|
|
if err := cfg.Validate(); err != nil {
|
||
|
|
return nil, fmt.Errorf("%w: %w", errCfg, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return cfg, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate validates app configuration.
|
||
|
|
func (c *Config) Validate() error {
|
||
|
|
if err := c.RSS.Validate(); err != nil {
|
||
|
|
return fmt.Errorf("validate configuration: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|