github.com/wfusion/gofusion@v1.1.14/common/utils/marshal.go (about)

     1  package utils
     2  
     3  import (
     4  	"encoding/gob"
     5  	"reflect"
     6  
     7  	"github.com/BurntSushi/toml"
     8  	"github.com/mitchellh/mapstructure"
     9  	"gopkg.in/yaml.v3"
    10  
    11  	"github.com/wfusion/gofusion/common/utils/serialize/json"
    12  )
    13  
    14  // JsonStringify for k8s ConfigMap, Secret
    15  type JsonStringify[T any] struct {
    16  	Value T
    17  }
    18  
    19  func (j *JsonStringify[T]) MarshalJSON() (output []byte, err error) {
    20  	var buf []byte
    21  	if buf, err = json.Marshal(j.Value); err != nil {
    22  		return
    23  	}
    24  	if output, err = json.Marshal(buf); err != nil {
    25  		return
    26  	}
    27  	return
    28  }
    29  
    30  func (j *JsonStringify[T]) UnmarshalJSON(input []byte) (err error) {
    31  	var buf string
    32  	if err = json.Unmarshal(input, &buf); err != nil {
    33  		return
    34  	}
    35  	if err = json.Unmarshal(UnsafeStringToBytes(buf), &j.Value); err != nil {
    36  		return
    37  	}
    38  	return
    39  }
    40  
    41  func MustJsonMarshal(s any) []byte             { return Must(json.Marshal(s)) }
    42  func MustJsonMarshalString(s any) string       { return string(MustJsonMarshal(s)) }
    43  func MustJsonUnmarshal[T any](s []byte) (t *T) { MustSuccess(json.Unmarshal(s, &t)); return }
    44  
    45  type unmarshalType string
    46  
    47  const (
    48  	UnmarshalTypeJson unmarshalType = "json"
    49  	UnmarshalTypeYaml unmarshalType = "yaml"
    50  	UnmarshalTypeToml unmarshalType = "toml"
    51  )
    52  
    53  // An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
    54  // (The argument to Unmarshal must be a non-nil pointer.)
    55  type InvalidUnmarshalError struct {
    56  	Type reflect.Type
    57  }
    58  
    59  func (e *InvalidUnmarshalError) Error() string {
    60  	if e.Type == nil {
    61  		return "common/utils: Unmarshal(nil)"
    62  	}
    63  
    64  	if e.Type.Kind() != reflect.Pointer {
    65  		return "common/utils: Unmarshal(non-pointer " + e.Type.String() + ")"
    66  	}
    67  	return "common/utils: Unmarshal(nil " + e.Type.String() + ")"
    68  }
    69  
    70  func Unmarshal(s, d any, tag unmarshalType) (err error) {
    71  	switch s.(type) {
    72  	case string, []byte:
    73  		bs, cb := BytesBufferPool.Get(nil)
    74  		defer cb()
    75  		if ss, ok := s.(string); ok {
    76  			bs.WriteString(ss)
    77  		} else {
    78  			bs.Write(s.([]byte))
    79  		}
    80  
    81  		switch tag {
    82  		case UnmarshalTypeJson:
    83  			return json.NewDecoder(bs).Decode(d)
    84  		case UnmarshalTypeYaml:
    85  			err = yaml.NewDecoder(bs).Decode(d)
    86  			return
    87  		case UnmarshalTypeToml:
    88  			_, err = toml.NewDecoder(bs).Decode(d)
    89  			return
    90  		default:
    91  			err = gob.NewDecoder(bs).Decode(d)
    92  			return
    93  		}
    94  	default:
    95  		cfg := &mapstructure.DecoderConfig{Result: d}
    96  		if tag != "" {
    97  			cfg.TagName = string(tag)
    98  		}
    99  
   100  		var dec *mapstructure.Decoder
   101  		if dec, err = mapstructure.NewDecoder(cfg); err != nil {
   102  			return
   103  		}
   104  		err = dec.Decode(s)
   105  		return
   106  	}
   107  }