github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/internal/build/request_body.go (about) 1 package build 2 3 import ( 4 "encoding/json" 5 "fmt" 6 ) 7 8 // Body wraps original request data providing root tag support. 9 // 10 // Example: 11 // 12 // wrapped := structure { 13 // Field string `json:"field"` 14 // } {"data"} 15 // 16 // Body{ 17 // RootTag: "root", 18 // Wrapped: wrapped, 19 // } 20 // 21 // Will produce the following json: 22 // 23 // { 24 // "root": {"field": "data"} 25 // } 26 type Body struct { 27 RootTag string 28 Wrapped interface{} 29 } 30 31 // prepared returns request body, wrapped into a root tag, if required. 32 func (r Body) prepared() interface{} { 33 if r.RootTag == "" { 34 return r.Wrapped 35 } 36 37 return map[string]interface{}{ 38 r.RootTag: r.Wrapped, 39 } 40 } 41 42 // MarshalJSON satisfies json.Marshaler interface. 43 func (r Body) MarshalJSON() ([]byte, error) { 44 return json.Marshal(r.prepared()) 45 } 46 47 // String allows simple pretty-print of prepared value. 48 func (r Body) String() string { 49 jsonData, err := json.MarshalIndent(r.prepared(), "", " ") 50 if err != nil { 51 return fmt.Sprintf("!err: %s", err.Error()) 52 } 53 54 return string(jsonData) 55 } 56 57 // RequestBody validates given structure by its tags and build the body ready to be marshalled to the JSON. 58 func RequestBody(opts interface{}, parent string) (*Body, error) { 59 if opts == nil { 60 return nil, fmt.Errorf("error building request body: %w", ErrNilOpts) 61 } 62 63 if err := ValidateTags(opts); err != nil { 64 return nil, fmt.Errorf("error building request body: %w", err) 65 } 66 67 return &Body{ 68 RootTag: parent, 69 Wrapped: opts, 70 }, nil 71 } 72 73 func (r Body) ToMap() (map[string]interface{}, error) { 74 var res map[string]interface{} 75 76 marshal, err := r.MarshalJSON() 77 if err != nil { 78 return nil, err 79 } 80 81 err = json.Unmarshal(marshal, &res) 82 return res, err 83 } 84 85 func RequestBodyMap(opts interface{}, parent string) (map[string]interface{}, error) { 86 body, err := RequestBody(opts, parent) 87 if err != nil { 88 return nil, err 89 } 90 91 return body.ToMap() 92 }