99 lines
2.9 KiB
Go
99 lines
2.9 KiB
Go
// Copyright (c) 2023 Joshua Rich <joshua.rich@gmail.com>
|
|
//
|
|
// This software is released under the MIT License.
|
|
// https://opensource.org/licenses/MIT
|
|
|
|
package config
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type AppConfig struct {
|
|
APIURL string `validate:"required"`
|
|
WebSocketURL string `validate:"required"`
|
|
Secret string
|
|
Token string `validate:"required"`
|
|
WebhookID string `validate:"required"`
|
|
}
|
|
|
|
type validationError struct {
|
|
Namespace string `json:"namespace"` // can differ when a custom TagNameFunc is registered or
|
|
Field string `json:"field"` // by passing alt name to ReportError like below
|
|
StructNamespace string `json:"structNamespace"`
|
|
StructField string `json:"structField"`
|
|
Tag string `json:"tag"`
|
|
ActualTag string `json:"actualTag"`
|
|
Kind string `json:"kind"`
|
|
Type string `json:"type"`
|
|
Value string `json:"value"`
|
|
Param string `json:"param"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// key is an unexported type for keys defined in this package.
|
|
// This prevents collisions with keys defined in other packages.
|
|
type key int
|
|
|
|
// configKey is the key for agent.AppConfig values in Contexts. It is
|
|
// unexported; clients use user.NewContext and user.FromContext
|
|
// instead of using this key directly.
|
|
var configKey key
|
|
|
|
// NewContext returns a new Context that carries value c.
|
|
func NewContext(ctx context.Context, c *AppConfig) context.Context {
|
|
return context.WithValue(ctx, configKey, c)
|
|
}
|
|
|
|
// FromContext returns the User value stored in ctx, if any.
|
|
func FromContext(ctx context.Context) (*AppConfig, bool) {
|
|
c, ok := ctx.Value(configKey).(*AppConfig)
|
|
return c, ok
|
|
}
|
|
|
|
func (config *AppConfig) Validate() error {
|
|
validate := validator.New()
|
|
err := validate.Struct(config)
|
|
if err != nil {
|
|
|
|
// this check is only needed when your code could produce
|
|
// an invalid value for validation such as interface with nil
|
|
// value most including myself do not usually have code like this.
|
|
if _, ok := err.(*validator.InvalidValidationError); ok {
|
|
return err
|
|
}
|
|
|
|
for _, err := range err.(validator.ValidationErrors) {
|
|
e := validationError{
|
|
Namespace: err.Namespace(),
|
|
Field: err.Field(),
|
|
StructNamespace: err.StructNamespace(),
|
|
StructField: err.StructField(),
|
|
Tag: err.Tag(),
|
|
ActualTag: err.ActualTag(),
|
|
Kind: fmt.Sprintf("%v", err.Kind()),
|
|
Type: fmt.Sprintf("%v", err.Type()),
|
|
Value: fmt.Sprintf("%v", err.Value()),
|
|
Param: err.Param(),
|
|
Message: err.Error(),
|
|
}
|
|
|
|
_, err := json.MarshalIndent(e, "", " ")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// from here you can create your own error messages in whatever language you wish
|
|
log.Debug().Caller().Msg("Config seems invalid.")
|
|
return errors.New("invalid config")
|
|
}
|
|
return nil
|
|
}
|