I want to parse a string to struct using reflection. But problem is that we have many different structs, which vary in value of "Type" field. First of all I convert string to map of key-values as following:
input string:
"[6001]\ntype = endpoint\ncontext = internal\ndisallow = all\nallow = ulaw\nallow = law\naors = 6001\nauth = auth6001"
converted to map:
map[Name:6001 allow:ulaw law aors:6001 auth:auth6001 context:internal disallow:all type:endpoint]
Before reflection we have to choose which of structs to create. Does it exist a way to choose it without hardcoding (writing special func for each structure)?
type All struct{
A
B
C
}
type A struct {
Type string
}
type B struct {
Type string
}
type C struct {
Name string
Type string
Context string
Disallow []string
Allow []string
Aors string
Auth string
}
input := "[6001]\ntype = endpoint\ncontext = internal\ndisallow = all\nallow = ulaw\nallow = law\naors = 6001\nauth = auth6001"
func getMap(input string) map[string]string {
input := "[6001]\ntype = endpoint\ncontext = internal\ndisallow = all\nallow = ulaw\nallow = law\naors = 6001\nauth = auth6001"
// remove spaces
input = regexp.MustCompile(`\p{Z}|(\;\S+)`).ReplaceAllString(ex, "")
rows := strings.Split(ex, "\n")
m := make(map[string]string)
// filling "Name" field
m["Name"] = strings.Trim(regexp.MustCompile(`\[[a-zA-Z0-9]{1,}\]`).FindString(ex), "[]")
// filling other fields
for i := 1; i < len(rows); i++ {
kv := strings.Split(rows[i], "=") // пара ключ-значение
if _, ok := m[kv[0]]; ok {
m[kv[0]] = fmt.Sprintf("%s %s", m[kv[0]], kv[1])
} else {
m[kv[0]] = kv[1]
}
}
return m
}
func (a *All) fillStruct(m map[string]string) {
a.C = Example{} // it should check m["type"] and then create the corresponding structure
val := reflect.ValueOf(&E).Elem()
for i := 0; i < val.NumField(); i++ {
f := val.Field(i)
name := under_score(val.Type().Field(i).Name) // "underscore" converts CamelCase to under_score
if _, ok := m[name]; !ok {
fmt.Println(name, ok)
continue
}
switch f.Kind() {
case reflect.Slice:
f.Set(reflect.ValueOf(strings.Split(m[name], " ")))
case reflect.String:
f.SetString("test")
default:
log.Println("unsupported field type", f.Kind())
}
}
}
Aucun commentaire:
Enregistrer un commentaire