github.com/maresnic/mr-kong@v1.0.0/resolver.go (about) 1 package kong 2 3 import ( 4 "encoding/json" 5 "io" 6 "strings" 7 ) 8 9 // A Resolver resolves a Flag value from an external source. 10 type Resolver interface { 11 // Validate configuration against Application. 12 // 13 // This can be used to validate that all provided configuration is valid within this application. 14 Validate(app *Application) error 15 16 // Resolve the value for a Flag. 17 Resolve(context *Context, parent *Path, flag *Flag) (interface{}, error) 18 } 19 20 // ResolverFunc is a convenience type for non-validating Resolvers. 21 type ResolverFunc func(context *Context, parent *Path, flag *Flag) (interface{}, error) 22 23 var _ Resolver = ResolverFunc(nil) 24 25 func (r ResolverFunc) Resolve(context *Context, parent *Path, flag *Flag) (interface{}, error) { //nolint: revive 26 return r(context, parent, flag) 27 } 28 func (r ResolverFunc) Validate(app *Application) error { return nil } //nolint: revive 29 30 // JSON returns a Resolver that retrieves values from a JSON source. 31 // 32 // Flag names are used as JSON keys indirectly, by tring snake_case and camelCase variants. 33 func JSON(r io.Reader) (Resolver, error) { 34 values := map[string]interface{}{} 35 err := json.NewDecoder(r).Decode(&values) 36 if err != nil { 37 return nil, err 38 } 39 var f ResolverFunc = func(context *Context, parent *Path, flag *Flag) (interface{}, error) { 40 name := strings.ReplaceAll(flag.Name, "-", "_") 41 snakeCaseName := snakeCase(flag.Name) 42 raw, ok := values[name] 43 if ok { 44 return raw, nil 45 } else if raw, ok = values[snakeCaseName]; ok { 46 return raw, nil 47 } 48 raw = values 49 for _, part := range strings.Split(name, ".") { 50 if values, ok := raw.(map[string]interface{}); ok { 51 raw, ok = values[part] 52 if !ok { 53 return nil, nil 54 } 55 } else { 56 return nil, nil 57 } 58 } 59 return raw, nil 60 } 61 62 return f, nil 63 } 64 65 func snakeCase(name string) string { 66 name = strings.Join(strings.Split(strings.Title(name), "-"), "") //nolint: staticcheck 67 return strings.ToLower(name[:1]) + name[1:] 68 }