I'm trying to parse some YAML file into go struct, but the file itself can not be treated as ordinary go structure: some of values may be either string or map[string][]string.
What I have tried is to do custom unmarshal func:
func (domain *Domain) UnmarshalYAML(unmarshal func(interface{}) error) error {
fmt.Println("Parsing domain")
var hostUrl interface{}
unmarshal(&hostUrl)
fmt.Println(reflect.TypeOf(hostUrl))
switch hostUrl.(type) {
case string:
domain.Host = hostUrl.(string)
case map[interface {}]interface {}:
fmt.Println("got map")
v := reflect.ValueOf(hostUrl)
fmt.Println(v.MapKeys()[0])
for _, host := range v.MapKeys() {
domain.Host = host.Interface().(string)
fmt.Println(v.MapIndex(host))
//HERE I NEED TO DO SMTH LIKE THIS:
//domain.Urls = v.MapIndex(host).([]string)
}
default:
return errors.New("invalid config file, cant parse domains")
}
return nil
}
My domain structure looks like this:
type Domain struct {
Host string
Urls []string
}
But this code causes an error:
invalid type assertion: v.MapIndex(host).([]string) (non-interface type reflect.Value on left)
So my question may sound like "how to convert {}interface to []string?" or it may become more complex: "How to parse YAML file into go struct if some key can be either simple string or map[string][]string?"
UPDATE: Responding to @mkopriva:
fmt.Println(v.MapIndex(host))
for url := range v.MapIndex(host).Interface().([] interface{}) {
fmt.Println(url)
}
Didnt help me, as now it just prints some integers (0), but there should be a string. Converting it to an array of strings throws another error:
panic: interface conversion: interface {} is []interface {}, not []string
reflect.Value.MapIndexdoes not return a value of typeinterface{}but of typereflect.Valuetherefore the type assertion won't compile.reflect.Valuehas a method calledInterfacethat returns it's underlying value asinterface{}, on it you can do type assertion. Or you can usereflect.Value'sKindmethod to figure out the underlying type of the interface and go from there. - mkopriva[]interface{}to[]T, you need to loop over each of theinterface{}items and assert them individually. Also note the example code is not guarding against possible panics due to invalid type assertions, you should use the "comma ok" idiom to avoid those. - mkoprivainvalid type assertion: url.(string) (non-interface type int on left)- Alex Mokeev