json.go raw

   1  package api
   2  
   3  import (
   4  	"reflect"
   5  
   6  	jsoniter "github.com/json-iterator/go"
   7  	"github.com/mimuret/golang-iij-dpf/pkg/meta"
   8  )
   9  
  10  var JSON = NewJSONAPIAdapter()
  11  
  12  func UnmarshalRead(bs []byte, o interface{}) error {
  13  	return JSON.UnmarshalRead(bs, o)
  14  }
  15  
  16  func MarshalCreate(body interface{}) ([]byte, error) {
  17  	return JSON.MarshalCreate(body)
  18  }
  19  
  20  func MarshalUpdate(body interface{}) ([]byte, error) {
  21  	return JSON.MarshalUpdate(body)
  22  }
  23  
  24  func MarshalApply(body interface{}) ([]byte, error) {
  25  	return JSON.MarshalApply(body)
  26  }
  27  
  28  func MarshalOutput(spec Spec) ([]byte, error) {
  29  	return JSON.MarshalOutput(spec)
  30  }
  31  
  32  func UnMarshalInput(bs []byte, obj Object) error {
  33  	return JSON.UnMarshalInput(bs, obj)
  34  }
  35  
  36  type JSONAPIInterface interface {
  37  	UnmarshalRead(bs []byte, o interface{}) error
  38  	MarshalCreate(body interface{}) ([]byte, error)
  39  	MarshalUpdate(body interface{}) ([]byte, error)
  40  	MarshalApply(body interface{}) ([]byte, error)
  41  }
  42  
  43  type JSONFileInterface interface {
  44  	MarshalOutput(spec Spec) ([]byte, error)
  45  	UnMarshalInput(bs []byte, obj Object) error
  46  }
  47  
  48  type JSONAPIAdapter struct {
  49  	Read   jsoniter.API
  50  	Update jsoniter.API
  51  	Create jsoniter.API
  52  	Apply  jsoniter.API
  53  	JSON   jsoniter.API
  54  }
  55  
  56  func NewJSONAPIAdapter() *JSONAPIAdapter {
  57  	return &JSONAPIAdapter{
  58  		Read: jsoniter.Config{
  59  			EscapeHTML:             true,
  60  			SortMapKeys:            false,
  61  			ValidateJsonRawMessage: true,
  62  			OnlyTaggedField:        true,
  63  			TagKey:                 "read",
  64  		}.Froze(),
  65  		Create: jsoniter.Config{
  66  			EscapeHTML:             true,
  67  			SortMapKeys:            true,
  68  			ValidateJsonRawMessage: true,
  69  			OnlyTaggedField:        true,
  70  			TagKey:                 "create",
  71  		}.Froze(),
  72  		Update: jsoniter.Config{
  73  			EscapeHTML:             true,
  74  			SortMapKeys:            true,
  75  			ValidateJsonRawMessage: true,
  76  			OnlyTaggedField:        true,
  77  			TagKey:                 "update",
  78  		}.Froze(),
  79  		Apply: jsoniter.Config{
  80  			EscapeHTML:             true,
  81  			SortMapKeys:            true,
  82  			ValidateJsonRawMessage: true,
  83  			OnlyTaggedField:        true,
  84  			TagKey:                 "apply",
  85  		}.Froze(),
  86  		JSON: jsoniter.Config{
  87  			EscapeHTML:             true,
  88  			SortMapKeys:            true,
  89  			ValidateJsonRawMessage: true,
  90  			OnlyTaggedField:        false,
  91  			TagKey:                 "json",
  92  		}.Froze(),
  93  	}
  94  }
  95  
  96  // Unmarshal api response.
  97  func (j *JSONAPIAdapter) UnmarshalRead(bs []byte, o interface{}) error {
  98  	return j.Read.Unmarshal(bs, o)
  99  }
 100  
 101  // Marshal for create request.
 102  func (j *JSONAPIAdapter) MarshalCreate(body interface{}) ([]byte, error) {
 103  	return j.Create.Marshal(body)
 104  }
 105  
 106  // Marshal for update request.
 107  func (j *JSONAPIAdapter) MarshalUpdate(body interface{}) ([]byte, error) {
 108  	return j.Update.Marshal(body)
 109  }
 110  
 111  // Marshal for apply request.
 112  func (j *JSONAPIAdapter) MarshalApply(body interface{}) ([]byte, error) {
 113  	return j.Apply.Marshal(body)
 114  }
 115  
 116  // file format frame.
 117  type OutputFrame struct {
 118  	meta.KindVersion `json:",inline"`
 119  	Resource         Object `json:"resource"`
 120  }
 121  
 122  // Marshal for file format.
 123  func (j *JSONAPIAdapter) MarshalOutput(spec Spec) ([]byte, error) {
 124  	t := reflect.TypeOf(spec)
 125  	t = t.Elem()
 126  	out := &OutputFrame{
 127  		KindVersion: meta.KindVersion{
 128  			Kind:       t.Name(),
 129  			APIVersion: spec.GetGroup(),
 130  		},
 131  		Resource: spec,
 132  	}
 133  	return j.JSON.Marshal(out)
 134  }
 135  
 136  // UnMarshal for file format.
 137  func (j *JSONAPIAdapter) UnMarshalInput(bs []byte, obj Object) error {
 138  	out := &OutputFrame{
 139  		Resource: obj,
 140  	}
 141  	return j.JSON.Unmarshal(bs, out)
 142  }
 143