1package xmpp 2 3import ( 4 "fmt" 5 "reflect" 6 "strconv" 7 8 "github.com/coyim/coyim/xmpp/data" 9) 10 11//Unlike xmpp.processForm() we are interested in getting values from forms 12//Not rendering them a UI widgets 13 14func parseForm(dstStructElementValue reflect.Value, form data.Form) error { 15 elem := dstStructElementValue.Elem() 16 dstType := elem.Type() 17 18 for i := 0; i < dstType.NumField(); i++ { 19 field := dstType.Field(i) 20 tag := field.Tag.Get("form-field") 21 if tag == "" { 22 continue 23 } 24 25 dstValue := elem.Field(i) 26 if !dstValue.CanSet() { 27 panic("struct element must be settable") 28 } 29 30 //Find value in the form 31 for _, f := range form.Fields { 32 if f.Var != tag { 33 continue 34 } 35 36 if 0 == len(f.Values) { 37 continue 38 } 39 40 switch f.Type { 41 case "text-single": 42 switch dstValue.Kind() { 43 case reflect.String: 44 dstValue.SetString(f.Values[0]) 45 case reflect.Int: 46 v, _ := strconv.ParseInt(f.Values[0], 0, 64) 47 dstValue.SetInt(v) 48 49 } 50 default: 51 //TODO 52 fmt.Printf("I dont know how to set %s fields\n", f.Type) 53 } 54 55 } 56 } 57 58 return nil 59} 60 61func parseForms(dst interface{}, forms []data.Form) error { 62 if reflect.TypeOf(dst).Kind() != reflect.Ptr { 63 panic("dst must be a pointer") 64 } 65 66 dstValue := reflect.ValueOf(dst) 67 dstType := dstValue.Elem().Type() 68 if dstType.Kind() != reflect.Struct { 69 panic("dst must be a struct value") 70 } 71 72 for _, f := range forms { 73 if f.XMLName.Space != "jabber:x:data" { 74 continue 75 } 76 77 if 0 == len(f.Fields) || f.Fields[0].Var != "FORM_TYPE" { 78 continue 79 } 80 81 if 0 == len(f.Fields[0].Values) { 82 continue 83 } 84 85 formType := f.Fields[0].Values[0] 86 87 for i := 0; i < dstType.NumField(); i++ { 88 tag := dstType.Field(i).Tag.Get("form-type") 89 if tag == "" { 90 continue 91 } 92 93 if tag != formType { 94 continue 95 } 96 } 97 98 return parseForm(dstValue, f) 99 } 100 101 return nil 102} 103