e1.0.1 Minor feature to register config with struct tag.

This commit is contained in:
2025-04-23 00:34:15 -04:00
parent e8519145c7
commit d8b12a2871
2 changed files with 70 additions and 2 deletions

View File

@ -207,7 +207,6 @@ func printLogConfig(cfg LogConfig) {
func verifyConfig(cfg LogConfig) {
allCorrect := true
// Check each modified value
if cfg.Level != 2 {
fmt.Printf("ERROR: Level is %d, expected 2\n", cfg.Level)
allCorrect = false
@ -238,7 +237,6 @@ func verifyConfig(cfg LogConfig) {
allCorrect = false
}
// Check that unmodified values retained their defaults
if cfg.Directory != "./logs" {
fmt.Printf("ERROR: Directory changed to %s, expected './logs'\n", cfg.Directory)
allCorrect = false

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"reflect"
"strconv"
"strings"
"sync"
@ -84,6 +85,75 @@ func (c *Config) Unregister(path string) error {
return nil
}
// RegisterStruct registers configuration values derived from a struct.
// It uses struct tags to determine the configuration paths.
// The prefix is prepended to all paths (e.g., "log.").
func (c *Config) RegisterStruct(prefix string, structWithDefaults interface{}) error {
v := reflect.ValueOf(structWithDefaults)
// Handle pointer or direct struct value
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
return fmt.Errorf("RegisterStruct requires a struct, got %T", structWithDefaults)
}
t := v.Type()
var firstErr error
for i := 0; i < v.NumField(); i++ {
field := t.Field(i)
fieldValue := v.Field(i)
// Skip unexported fields
if !field.IsExported() {
continue
}
// Get tag value or use field name
tag := field.Tag.Get("toml")
if tag == "-" {
continue // Skip this field
}
// Extract tag name or use field name
key := field.Name
if tag != "" {
parts := strings.Split(tag, ",")
if parts[0] != "" {
key = parts[0]
}
}
// Build full path
path := prefix + key
// Register this field
if err := c.Register(path, fieldValue.Interface()); err != nil && firstErr == nil {
firstErr = err
}
}
return firstErr
}
// GetRegisteredPaths returns all registered configuration paths with the specified prefix.
func (c *Config) GetRegisteredPaths(prefix string) map[string]bool {
c.mutex.RLock()
defer c.mutex.RUnlock()
result := make(map[string]bool)
for path := range c.items {
if strings.HasPrefix(path, prefix) {
result[path] = true
}
}
return result
}
// Get retrieves a configuration value using the path.
// It returns the current value (or default if not explicitly set).
// The second return value indicates if the path was registered.