github.com/akamai/AkamaiOPEN-edgegrid-golang@v1.2.2/jsonhooks-v1/jsonhooks.go (about)

     1  // Package jsonhooks adds hooks that are automatically called before JSON marshaling (PreMarshalJSON) and
     2  // after JSON unmarshaling (PostUnmarshalJSON). It does not do so recursively.
     3  package jsonhooks
     4  
     5  import (
     6  	"encoding/json"
     7  	"reflect"
     8  )
     9  
    10  // Marshal wraps encoding/json.Marshal, calls v.PreMarshalJSON() if it exists
    11  func Marshal(v interface{}) ([]byte, error) {
    12  	if ImplementsPreJSONMarshaler(v) {
    13  		err := v.(PreJSONMarshaler).PreMarshalJSON()
    14  		if err != nil {
    15  			return nil, err
    16  		}
    17  	}
    18  
    19  	return json.Marshal(v)
    20  }
    21  
    22  // Unmarshal wraps encoding/json.Unmarshal, calls v.PostUnmarshalJSON() if it exists
    23  func Unmarshal(data []byte, v interface{}) error {
    24  	err := json.Unmarshal(data, v)
    25  	if err != nil {
    26  		return err
    27  	}
    28  
    29  	if ImplementsPostJSONUnmarshaler(v) {
    30  		err := v.(PostJSONUnmarshaler).PostUnmarshalJSON()
    31  		if err != nil {
    32  			return err
    33  		}
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  // PreJSONMarshaler infers support for the PreMarshalJSON pre-hook
    40  type PreJSONMarshaler interface {
    41  	PreMarshalJSON() error
    42  }
    43  
    44  // ImplementsPreJSONMarshaler checks for support for the PreMarshalJSON pre-hook
    45  func ImplementsPreJSONMarshaler(v interface{}) bool {
    46  	value := reflect.ValueOf(v)
    47  	if !value.IsValid() {
    48  		return false
    49  	}
    50  
    51  	_, ok := value.Interface().(PreJSONMarshaler)
    52  	return ok
    53  }
    54  
    55  // PostJSONUnmarshaler infers support for the PostUnmarshalJSON post-hook
    56  type PostJSONUnmarshaler interface {
    57  	PostUnmarshalJSON() error
    58  }
    59  
    60  // ImplementsPostJSONUnmarshaler checks for support for the PostUnmarshalJSON post-hook
    61  func ImplementsPostJSONUnmarshaler(v interface{}) bool {
    62  	value := reflect.ValueOf(v)
    63  	if value.Kind() == reflect.Ptr && value.IsNil() {
    64  		return false
    65  	}
    66  
    67  	_, ok := value.Interface().(PostJSONUnmarshaler)
    68  	return ok
    69  }