github.com/CiscoM31/godata@v1.0.10/response_model.go (about) 1 package godata 2 3 import ( 4 "bytes" 5 "strconv" 6 ) 7 8 // A response is a dictionary of keys to their corresponding fields. This will 9 // be converted into a JSON dictionary in the response to the web client. 10 type GoDataResponse struct { 11 Fields map[string]*GoDataResponseField 12 } 13 14 // Serialize the result as JSON for sending to the client. If an error 15 // occurs during the serialization, it will be returned. 16 func (r *GoDataResponse) Json() ([]byte, error) { 17 result, err := prepareJsonDict(r.Fields) 18 if err != nil { 19 return nil, err 20 } 21 return result, nil 22 } 23 24 // A response that is a primitive JSON type or a list or a dictionary. When 25 // writing to JSON, it is automatically mapped from the Go type to a suitable 26 // JSON data type. Any type can be used, but if the data type is not supported 27 // for serialization, then an error is thrown. 28 type GoDataResponseField struct { 29 Value interface{} 30 } 31 32 // Convert the response field to a JSON serialized form. If the type is not 33 // string, []byte, int, float64, map[string]*GoDataResponseField, or 34 // []*GoDataResponseField, then an error will be thrown. 35 func (f *GoDataResponseField) Json() ([]byte, error) { 36 switch f.Value.(type) { 37 case string: 38 return prepareJsonString([]byte(f.Value.(string))) 39 case []byte: 40 return prepareJsonString(f.Value.([]byte)) 41 case int: 42 return []byte(strconv.Itoa(f.Value.(int))), nil 43 case float64: 44 return []byte(strconv.FormatFloat(f.Value.(float64), 'f', -1, 64)), nil 45 case map[string]*GoDataResponseField: 46 return prepareJsonDict(f.Value.(map[string]*GoDataResponseField)) 47 case []*GoDataResponseField: 48 return prepareJsonList(f.Value.([]*GoDataResponseField)) 49 default: 50 return nil, InternalServerError("Response field type not recognized.") 51 } 52 } 53 54 func prepareJsonString(s []byte) ([]byte, error) { 55 // escape double quotes 56 s = bytes.Replace(s, []byte("\""), []byte("\\\""), -1) 57 var buf bytes.Buffer 58 buf.WriteByte('"') 59 buf.Write(s) 60 buf.WriteByte('"') 61 return buf.Bytes(), nil 62 } 63 64 func prepareJsonDict(d map[string]*GoDataResponseField) ([]byte, error) { 65 var buf bytes.Buffer 66 buf.WriteByte('{') 67 count := 0 68 for k, v := range d { 69 buf.WriteByte('"') 70 buf.Write([]byte(k)) 71 buf.WriteByte('"') 72 buf.WriteByte(':') 73 field, err := v.Json() 74 if err != nil { 75 return nil, err 76 } 77 buf.Write(field) 78 count++ 79 if count < len(d) { 80 buf.WriteByte(',') 81 } 82 } 83 buf.WriteByte('}') 84 return buf.Bytes(), nil 85 } 86 87 func prepareJsonList(l []*GoDataResponseField) ([]byte, error) { 88 var buf bytes.Buffer 89 buf.WriteByte('[') 90 count := 0 91 for _, v := range l { 92 field, err := v.Json() 93 if err != nil { 94 return nil, err 95 } 96 buf.Write(field) 97 count++ 98 if count < len(l) { 99 buf.WriteByte(',') 100 } 101 } 102 buf.WriteByte(']') 103 return buf.Bytes(), nil 104 }