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 }