Add support for maps defined as a json string
This commit is contained in:
		
							rodzic
							
								
									acbeb36b90
								
							
						
					
					
						commit
						33daad0a0d
					
				
							
								
								
									
										22
									
								
								cast_test.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								cast_test.go
									
									
									
									
									
								
							@ -697,6 +697,10 @@ func TestStringMapStringSliceE(t *testing.T) {
 | 
				
			|||||||
	var stringMapInterface1 = map[string]interface{}{"key 1": []string{"value 1"}, "key 2": []string{"value 2"}}
 | 
						var stringMapInterface1 = map[string]interface{}{"key 1": []string{"value 1"}, "key 2": []string{"value 2"}}
 | 
				
			||||||
	var stringMapInterfaceResult1 = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}}
 | 
						var stringMapInterfaceResult1 = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var jsonStringMapString = `{"key 1": "value 1", "key 2": "value 2"}`
 | 
				
			||||||
 | 
						var jsonStringMapStringArray = `{"key 1": ["value 1"], "key 2": ["value 2", "value 3"]}`
 | 
				
			||||||
 | 
						var jsonStringMapStringArrayResult = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2", "value 3"}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type Key struct {
 | 
						type Key struct {
 | 
				
			||||||
		k string
 | 
							k string
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -718,11 +722,15 @@ func TestStringMapStringSliceE(t *testing.T) {
 | 
				
			|||||||
		{interfaceMapInterfaceSlice, stringMapStringSlice, false},
 | 
							{interfaceMapInterfaceSlice, stringMapStringSlice, false},
 | 
				
			||||||
		{interfaceMapString, stringMapStringSingleSliceFieldsResult, false},
 | 
							{interfaceMapString, stringMapStringSingleSliceFieldsResult, false},
 | 
				
			||||||
		{interfaceMapInterface, stringMapStringSingleSliceFieldsResult, false},
 | 
							{interfaceMapInterface, stringMapStringSingleSliceFieldsResult, false},
 | 
				
			||||||
 | 
							{jsonStringMapStringArray, jsonStringMapStringArrayResult, false},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// errors
 | 
							// errors
 | 
				
			||||||
		{nil, nil, true},
 | 
							{nil, nil, true},
 | 
				
			||||||
		{testing.T{}, nil, true},
 | 
							{testing.T{}, nil, true},
 | 
				
			||||||
		{map[interface{}]interface{}{"foo": testing.T{}}, nil, true},
 | 
							{map[interface{}]interface{}{"foo": testing.T{}}, nil, true},
 | 
				
			||||||
		{map[interface{}]interface{}{Key{"foo"}: "bar"}, nil, true}, // ToStringE(Key{"foo"}) should fail
 | 
							{map[interface{}]interface{}{Key{"foo"}: "bar"}, nil, true}, // ToStringE(Key{"foo"}) should fail
 | 
				
			||||||
 | 
							{jsonStringMapString, nil, true},
 | 
				
			||||||
 | 
							{"", nil, true},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, test := range tests {
 | 
						for i, test := range tests {
 | 
				
			||||||
@ -751,9 +759,13 @@ func TestToStringMapE(t *testing.T) {
 | 
				
			|||||||
	}{
 | 
						}{
 | 
				
			||||||
		{map[interface{}]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
 | 
							{map[interface{}]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
 | 
				
			||||||
		{map[string]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
 | 
							{map[string]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
 | 
				
			||||||
 | 
							{`{"tag": "tags", "group": "groups"}`, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
 | 
				
			||||||
 | 
							{`{"tag": "tags", "group": true}`, map[string]interface{}{"tag": "tags", "group": true}, false},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// errors
 | 
							// errors
 | 
				
			||||||
		{nil, nil, true},
 | 
							{nil, nil, true},
 | 
				
			||||||
		{testing.T{}, nil, true},
 | 
							{testing.T{}, nil, true},
 | 
				
			||||||
 | 
							{"", nil, true},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, test := range tests {
 | 
						for i, test := range tests {
 | 
				
			||||||
@ -783,9 +795,12 @@ func TestToStringMapBoolE(t *testing.T) {
 | 
				
			|||||||
		{map[interface{}]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
 | 
							{map[interface{}]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
 | 
				
			||||||
		{map[string]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
 | 
							{map[string]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
 | 
				
			||||||
		{map[string]bool{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
 | 
							{map[string]bool{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
 | 
				
			||||||
 | 
							{`{"v1": true, "v2": false}`, map[string]bool{"v1": true, "v2": false}, false},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// errors
 | 
							// errors
 | 
				
			||||||
		{nil, nil, true},
 | 
							{nil, nil, true},
 | 
				
			||||||
		{testing.T{}, nil, true},
 | 
							{testing.T{}, nil, true},
 | 
				
			||||||
 | 
							{"", nil, true},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, test := range tests {
 | 
						for i, test := range tests {
 | 
				
			||||||
@ -811,6 +826,9 @@ func TestToStringMapStringE(t *testing.T) {
 | 
				
			|||||||
	var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
 | 
						var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
 | 
				
			||||||
	var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
 | 
						var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
 | 
				
			||||||
	var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
 | 
						var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
 | 
				
			||||||
 | 
						var jsonString = `{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}`
 | 
				
			||||||
 | 
						var invalidJsonString = `{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"`
 | 
				
			||||||
 | 
						var emptyString = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		input  interface{}
 | 
							input  interface{}
 | 
				
			||||||
@ -821,9 +839,13 @@ func TestToStringMapStringE(t *testing.T) {
 | 
				
			|||||||
		{stringMapInterface, stringMapString, false},
 | 
							{stringMapInterface, stringMapString, false},
 | 
				
			||||||
		{interfaceMapString, stringMapString, false},
 | 
							{interfaceMapString, stringMapString, false},
 | 
				
			||||||
		{interfaceMapInterface, stringMapString, false},
 | 
							{interfaceMapInterface, stringMapString, false},
 | 
				
			||||||
 | 
							{jsonString, stringMapString, false},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// errors
 | 
							// errors
 | 
				
			||||||
		{nil, nil, true},
 | 
							{nil, nil, true},
 | 
				
			||||||
		{testing.T{}, nil, true},
 | 
							{testing.T{}, nil, true},
 | 
				
			||||||
 | 
							{invalidJsonString, nil, true},
 | 
				
			||||||
 | 
							{emptyString, nil, true},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, test := range tests {
 | 
						for i, test := range tests {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								caste.go
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								caste.go
									
									
									
									
									
								
							@ -6,6 +6,7 @@
 | 
				
			|||||||
package cast
 | 
					package cast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"html/template"
 | 
						"html/template"
 | 
				
			||||||
@ -872,6 +873,9 @@ func ToStringMapStringE(i interface{}) (map[string]string, error) {
 | 
				
			|||||||
			m[ToString(k)] = ToString(val)
 | 
								m[ToString(k)] = ToString(val)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return m, nil
 | 
							return m, nil
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							err := jsonStringToObject(v, &m)
 | 
				
			||||||
 | 
							return m, err
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
 | 
							return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -932,6 +936,9 @@ func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			m[key] = value
 | 
								m[key] = value
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							err := jsonStringToObject(v, &m)
 | 
				
			||||||
 | 
							return m, err
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
 | 
							return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -955,6 +962,9 @@ func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
 | 
				
			|||||||
		return m, nil
 | 
							return m, nil
 | 
				
			||||||
	case map[string]bool:
 | 
						case map[string]bool:
 | 
				
			||||||
		return v, nil
 | 
							return v, nil
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							err := jsonStringToObject(v, &m)
 | 
				
			||||||
 | 
							return m, err
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
 | 
							return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -972,6 +982,9 @@ func ToStringMapE(i interface{}) (map[string]interface{}, error) {
 | 
				
			|||||||
		return m, nil
 | 
							return m, nil
 | 
				
			||||||
	case map[string]interface{}:
 | 
						case map[string]interface{}:
 | 
				
			||||||
		return v, nil
 | 
							return v, nil
 | 
				
			||||||
 | 
						case string:
 | 
				
			||||||
 | 
							err := jsonStringToObject(v, &m)
 | 
				
			||||||
 | 
							return m, err
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
 | 
							return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -1144,3 +1157,10 @@ func parseDateWith(s string, dates []string) (d time.Time, e error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return d, fmt.Errorf("unable to parse date: %s", s)
 | 
						return d, fmt.Errorf("unable to parse date: %s", s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// jsonStringToObject attempts to unmarshall a string as JSON into
 | 
				
			||||||
 | 
					// the object passed as pointer.
 | 
				
			||||||
 | 
					func jsonStringToObject(s string, v interface{}) error {
 | 
				
			||||||
 | 
						data := []byte(s)
 | 
				
			||||||
 | 
						return json.Unmarshal(data, v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Ładowanie…
	
		Reference in New Issue
	
	Block a user