@ -3,6 +3,7 @@ package altsrc
import (
"fmt"
"reflect"
"strings"
"time"
"github.com/codegangsta/cli"
@ -11,7 +12,31 @@ import (
// MapInputSource implements InputSourceContext to return
// data from the map that is loaded.
type MapInputSource struct {
valueMap map [ string ] interface { }
valueMap map [ interface { } ] interface { }
}
// nestedVal checks if the name has '.' delimiters.
// If so, it tries to traverse the tree by the '.' delimited sections to find
// a nested value for the key.
func nestedVal ( name string , tree map [ interface { } ] interface { } ) ( interface { } , bool ) {
if sections := strings . Split ( name , "." ) ; len ( sections ) > 1 {
node := tree
for _ , section := range sections [ : len ( sections ) - 1 ] {
if child , ok := node [ section ] ; ! ok {
return nil , false
} else {
if ctype , ok := child . ( map [ interface { } ] interface { } ) ; ! ok {
return nil , false
} else {
node = ctype
}
}
}
if val , ok := node [ sections [ len ( sections ) - 1 ] ] ; ok {
return val , true
}
}
return nil , false
}
// Int returns an int from the map if it exists otherwise returns 0
@ -22,7 +47,14 @@ func (fsm *MapInputSource) Int(name string) (int, error) {
if ! isType {
return 0 , incorrectTypeForFlagError ( name , "int" , otherGenericValue )
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( int )
if ! isType {
return 0 , incorrectTypeForFlagError ( name , "int" , nestedGenericValue )
}
return otherValue , nil
}
@ -39,6 +71,14 @@ func (fsm *MapInputSource) Duration(name string) (time.Duration, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( time . Duration )
if ! isType {
return 0 , incorrectTypeForFlagError ( name , "duration" , nestedGenericValue )
}
return otherValue , nil
}
return 0 , nil
}
@ -53,6 +93,14 @@ func (fsm *MapInputSource) Float64(name string) (float64, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( float64 )
if ! isType {
return 0 , incorrectTypeForFlagError ( name , "float64" , nestedGenericValue )
}
return otherValue , nil
}
return 0 , nil
}
@ -67,6 +115,14 @@ func (fsm *MapInputSource) String(name string) (string, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( string )
if ! isType {
return "" , incorrectTypeForFlagError ( name , "string" , nestedGenericValue )
}
return otherValue , nil
}
return "" , nil
}
@ -81,6 +137,14 @@ func (fsm *MapInputSource) StringSlice(name string) ([]string, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( [ ] string )
if ! isType {
return nil , incorrectTypeForFlagError ( name , "[]string" , nestedGenericValue )
}
return otherValue , nil
}
return nil , nil
}
@ -95,6 +159,14 @@ func (fsm *MapInputSource) IntSlice(name string) ([]int, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( [ ] int )
if ! isType {
return nil , incorrectTypeForFlagError ( name , "[]int" , nestedGenericValue )
}
return otherValue , nil
}
return nil , nil
}
@ -109,6 +181,14 @@ func (fsm *MapInputSource) Generic(name string) (cli.Generic, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( cli . Generic )
if ! isType {
return nil , incorrectTypeForFlagError ( name , "cli.Generic" , nestedGenericValue )
}
return otherValue , nil
}
return nil , nil
}
@ -123,6 +203,14 @@ func (fsm *MapInputSource) Bool(name string) (bool, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( bool )
if ! isType {
return false , incorrectTypeForFlagError ( name , "bool" , nestedGenericValue )
}
return otherValue , nil
}
return false , nil
}
@ -137,6 +225,14 @@ func (fsm *MapInputSource) BoolT(name string) (bool, error) {
}
return otherValue , nil
}
nestedGenericValue , exists := nestedVal ( name , fsm . valueMap )
if exists {
otherValue , isType := nestedGenericValue . ( bool )
if ! isType {
return true , incorrectTypeForFlagError ( name , "bool" , nestedGenericValue )
}
return otherValue , nil
}
return true , nil
}