From 7b9b034802e7f2163156312a5e19bac56d50eaf3 Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Thu, 5 Dec 2024 19:20:15 +0100 Subject: [PATCH] update --- go.mod | 5 +++++ go.sum | 4 ++++ gonfig.go | 55 +++++++++++++++++++++++++++++++++---------------------- 3 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 go.sum diff --git a/go.mod b/go.mod index 3185c98..00d81bb 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module github.com/lukaswrz/gonfig go 1.23.3 + +require ( + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6a62c36 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= diff --git a/gonfig.go b/gonfig.go index 579f712..6afec55 100644 --- a/gonfig.go +++ b/gonfig.go @@ -8,46 +8,57 @@ import ( "os" ) -// Validator defines an interface for validating a configuration of type T. It -// ensures that the provided configuration meets required constraints. -type Validator[T any] interface { - // Validate checks the provided configuration and returns an error if it is - // invalid. - Validate(config T) []error -} +// UnmarshalFunc is a function that unmarshals raw bytes into a configuration +// object of type T. +type UnmarshalFunc[T any] func([]byte, T) error + +// ValidateFunc is a function that validates a configuration object of type T +// and returns an error if validation fails. +type ValidateFunc[T any] func(T) error // ReadConfig reads a configuration file, unmarshals its content into the given -// configuration object, and validates it using the provided validator. If the -// primary path is empty, it searches for the configuration file in the -// fallback paths. The function returns the resolved path to the configuration -// file or a list of errors if the file cannot be located, read, unmarshaled, -// or validated. -func ReadConfig[T any](path string, paths []string, c *T, unmarshal func([]byte, *T) error, validator Validator[T]) (string, []error) { +// configuration object, and validates it. +// +// If the primary path is empty, it searches for the configuration file in the +// fallback paths. Returns the resolved path or an error if the file cannot be +// located, read, unmarshaled, or validated. +func ReadConfig[T any](path string, searchPaths []string, c *T, unmarshal UnmarshalFunc[*T], validate ValidateFunc[T]) (string, error) { var err error - path, err = findConfig(path, paths) + path, err = FindConfig(path, searchPaths) if err != nil { - return "", []error{err} + return "", err } + return path, ReadFoundConfig(path, c, unmarshal, validate) +} + +// ReadFoundConfig reads and processes a configuration file from a known path. +// +// Unmarshals the file's content into the given configuration object and +// validates it. Returns an error if the file cannot be read, unmarshaled, or +// validated. +func ReadFoundConfig[T any](path string, c *T, unmarshal UnmarshalFunc[*T], validate ValidateFunc[T]) error { content, err := os.ReadFile(path) if err != nil { - return "", []error{fmt.Errorf("unable to read configuration file %s: %w", path, err)} + return fmt.Errorf("unable to read configuration file %s: %w", path, err) } err = unmarshal(content, c) if err != nil { - return "", []error{fmt.Errorf("unable to unmarshal configuration file %s: %w", path, err)} + return fmt.Errorf("unable to unmarshal configuration file %s: %w", path, err) } - return path, validator.Validate(*c) + return validate(*c) } -// findConfig determines the path to the configuration file by using the +// FindConfig determines the path to the configuration file by using the // provided primary path or searching through a list of fallback paths if the -// primary path is empty. If no valid file is found, or if the specified file is -// inaccessible, an error is returned. -func findConfig(path string, paths []string) (string, error) { +// primary path is empty. +// +// Returns the resolved path or an error if no valid file is found or if the +// file is inaccessible. +func FindConfig(path string, paths []string) (string, error) { var err error if path == "" {