config.*fileConfiguration.Validate   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 15
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 15
nop 0
dl 0
loc 15
ccs 1
cts 1
cp 1
crap 1
rs 9.65
c 0
b 0
f 0
1
package config
2
3
import (
4
	"context"
5
	"fmt"
6
	"os"
7
	"strings"
8
9
	"github.com/muonsoft/validation"
10
	"github.com/muonsoft/validation/it"
11
	"github.com/muonsoft/validation/validator"
12
	"gopkg.in/yaml.v3"
13
)
14
15
type fileConfiguration struct {
16
	OpenAPI     openapiConfiguration     `json:"openapi" yaml:"openapi"`
17
	HTTP        httpConfiguration        `json:"http" yaml:"http"`
18
	Application applicationConfiguration `json:"application" yaml:"application"`
19
	Generation  generationConfiguration  `json:"generation" yaml:"generation"`
20
}
21
22
type openapiConfiguration struct {
23
	SpecificationURL string `json:"specification_url" yaml:"specification_url"`
24
	urlFromEnv       bool
25
}
26
27
type httpConfiguration struct {
28
	Port            *uint16 `json:"port" yaml:"port"`
29
	CORSEnabled     bool    `json:"cors_enabled" yaml:"cors_enabled"`
30
	ResponseTimeout float64 `json:"response_timeout" yaml:"response_timeout"`
31
}
32
33
type applicationConfiguration struct {
34
	Debug     bool   `json:"debug" yaml:"debug"`
35
	LogFormat string `json:"log_format" yaml:"log_format"`
36
	LogLevel  string `json:"log_level" yaml:"log_level"`
37
}
38
39
type generationConfiguration struct {
40
	DefaultMinFloat *float64 `json:"default_min_float" yaml:"default_min_float"`
41
	DefaultMaxFloat *float64 `json:"default_max_float" yaml:"default_max_float"`
42
	DefaultMinInt   *int64   `json:"default_min_int" yaml:"default_min_int"`
43
	DefaultMaxInt   *int64   `json:"default_max_int" yaml:"default_max_int"`
44
	NullProbability *float64 `json:"null_probability" yaml:"null_probability"`
45
	SuppressErrors  bool     `json:"suppress_errors" yaml:"suppress_errors"`
46
	UseExamples     string   `json:"use_examples" yaml:"use_examples"`
47
}
48
49 1
func loadFileConfiguration(filename string) (*fileConfiguration, error) {
50 1
	data, err := os.ReadFile(filename)
51 1
	if err != nil {
52
		return nil, &LoadingFailedError{Previous: err}
53
	}
54 1
55 1
	var fileConfig fileConfiguration
56 1
	err = yaml.Unmarshal(data, &fileConfig)
57 1
	if err != nil {
58
		return nil, &LoadingFailedError{Previous: err}
59
	}
60 1
61
	return &fileConfig, nil
62
}
63
64
var logFormats = []string{"tty", "json"}
65
var logLevels = []string{"panic", "fatal", "error", "warn", "warning", "info", "debug", "trace"}
66
var useExampleOptions = []string{"no", "if_present", "exclusively"}
67
68
var invalidLogFormat = fmt.Sprintf("must be one of: %s", strings.Join(logFormats, ", "))
69
var invalidLogLevel = fmt.Sprintf("must be one of: %s", strings.Join(logLevels, ", "))
70
var invalidUseExample = fmt.Sprintf("must be one of: %s", strings.Join(useExampleOptions, ", "))
71
72 1
func (config *fileConfiguration) Validate() error {
73
	return validator.Validate(
74
		context.Background(),
75
		validation.String(config.Application.LogFormat, it.IsOneOf(logFormats...).WithMessage(invalidLogFormat)).
76
			At(validation.PropertyName("application"), validation.PropertyName("log_format")),
77
		validation.String(config.Application.LogLevel, it.IsOneOf(logLevels...).WithMessage(invalidLogLevel)).
78
			At(validation.PropertyName("application"), validation.PropertyName("log_level")),
79
		validation.String(config.Generation.UseExamples, it.IsOneOf(useExampleOptions...).WithMessage(invalidUseExample)).
80
			At(validation.PropertyName("generation"), validation.PropertyName("use_examples")),
81
		validation.NilNumber[uint16](
82
			config.HTTP.Port,
83
			it.IsBetween[uint16](1, 65535).
84
				When(config.HTTP.Port != nil).
85
				WithMessage("value should be between {{ min }} and {{ max }} if present"),
86
		).At(validation.PropertyName("http"), validation.PropertyName("port")),
87
	)
88
}
89