summaryrefslogtreecommitdiff
path: root/config/config.go
blob: 6d379040b8846f58197f81ce9a43811996bbcd32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package config

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/go-playground/validator/v10"
)

type Config struct {
	Input  InputConfig  `json:"Input" validate:"required"`
	Output OutputConfig `json:"Output" validate:"required"`
}

type InputConfig struct {
	Storage StorageConfig `json:"Storage" validate:"required"`
}

type OutputConfig struct {
	Storage StorageConfig `json:"Storage" validate:"required"`
	Quality int           `json:"Quality" validate:"required,min=1,max=100"`
	Size    SizeConfig    `json:"Size" validate:"required"`
}

type StorageConfig struct {
	Type   string `json:"Type" validate:"required,oneof=b2 local"`
	Config any    `json:"Config" validate:"required"`
}

func (sc *StorageConfig) UnmarshalJSON(data []byte) error {
	var tmp struct {
		Type   string          `json:"Type"`
		Config json.RawMessage `json:"Config"`
	}

	if err := json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	sc.Type = tmp.Type

	switch tmp.Type {
	case "b2":
		var b2Config B2Config
		if err := json.Unmarshal(tmp.Config, &b2Config); err != nil {
			return fmt.Errorf("unmarshal B2Config: %w", err)
		}
		sc.Config = b2Config
	case "local":
		var localConfig LocalConfig
		if err := json.Unmarshal(tmp.Config, &localConfig); err != nil {
			return fmt.Errorf("unmarshal LocalConfig: %w", err)
		}
		sc.Config = localConfig
	default:
		return fmt.Errorf("unsupported storage type: %s", tmp.Type)
	}

	return nil
}

type B2Config struct {
	BucketName     string `json:"BucketName" validate:"required,min=1"`
	Region         string `json:"Region" validate:"required,min=1"`
	Prefix         string `json:"Prefix"`
	KeyID          string `json:"KeyID"`
	ApplicationKey string `json:"ApplicationKey"`
}

type LocalConfig struct {
	Path string `json:"Path" validate:"required,min=1"`
}

type SizeConfig struct {
	MaxWidth  int `json:"MaxWidth" validate:"required,min=0"`
	MaxHeight int `json:"MaxHeight" validate:"required,min=0"`
}

func LoadConfig(path string, config *Config) error {
	fileBytes, err := os.ReadFile(path)
	if err != nil {
		return err
	}

	expandedFileBytes := []byte(os.ExpandEnv(string(fileBytes)))

	if err = json.Unmarshal(expandedFileBytes, config); err != nil {
		return err
	}

	return nil
}

func InitConfig(path string) (*Config, error) {
	config := &Config{}
	if err := LoadConfig(path, config); err != nil {
		return nil, err
	}

	validate := validator.New(validator.WithRequiredStructEnabled())
	if err := validate.Struct(config); err != nil {
		return nil, err
	}

	return config, nil
}