Select Git revision
telemetry_middleware.go
field_json.go 1.86 KiB
package field
import (
"encoding/json"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)
type FieldData Field
type jsonField struct {
FieldData
Type string `json:"type"`
Params json.RawMessage `json:"params,omitempty"`
}
type ParametersConverter interface {
ConvertParameters(p Parameters) (Parameters, error)
}
type ParametersValidator interface {
ValidateParameters(p Parameters) error
}
func (f *Field) UnmarshalJSON(b []byte) error {
var j jsonField
if err := jsoniter.Unmarshal(b, &j); err != nil {
return errors.Wrapf(err, "error unmarshal json into field")
}
typ, ok := GetType(j.Type)
jsonParams := j.Params
// Unknown type, создаем поля Unknown которое будет хранить оригинальные параметры
if !ok {
*f = Field(j.FieldData)
f.Params = &UnknownParameters{Typ: j.Type, Params: jsonParams}
return nil
}
params := typ.NewParameters()
if len(j.Params) > 0 {
if err := jsoniter.Unmarshal(jsonParams, params); err != nil {
return errors.Wrapf(err, "error unmarshal json into field type %s", typ.Name())
}
}
if converter, ok := typ.(ParametersConverter); ok {
var err error
if params, err = converter.ConvertParameters(params); err != nil {
return errors.Wrap(err, "error unmarshal json")
}
}
if validator, ok := typ.(ParametersValidator); ok {
var err error
if err = validator.ValidateParameters(params); err != nil {
return errors.Wrap(err, "error validate json")
}
}
j.FieldData.State = f.State
*f = Field(j.FieldData)
f.Params = params
_ = f.Prepare()
return nil
}
func (f *Field) MarshalJSON() ([]byte, error) {
j := jsonField{
FieldData: FieldData(*f),
}
j.Type = f.GetType().Name()
if f.Params != nil {
b, err := jsoniter.Marshal(f.Params)
if err != nil {
return nil, err
}
j.Params = b
}
return jsoniter.Marshal(&j)
}