github.com/spi-ca/misc@v1.0.1/types/json.go (about) 1 package types 2 3 import ( 4 "database/sql/driver" 5 "encoding/json" 6 "github.com/pkg/errors" 7 "github.com/spi-ca/misc" 8 "github.com/spi-ca/misc/strutil" 9 ) 10 11 // JSON is an alias for json.RawMessage, which is 12 // a []byte underneath. 13 // JSON implements Marshal and Unmarshal. 14 type JSON json.RawMessage 15 16 // String output your JSON. 17 func (j JSON) String() string { 18 return strutil.B2S(j) 19 } 20 21 // Unmarshal your JSON variable into dest. 22 func (j JSON) Unmarshal(dest any) error { 23 iter := misc.JSONCodec.BorrowIterator(j) 24 defer misc.JSONCodec.ReturnIterator(iter) 25 iter.ReadVal(dest) 26 return iter.Error 27 } 28 29 // Marshal obj into your JSON variable. 30 func (j *JSON) Marshal(obj any) (err error) { 31 stream := misc.JSONCodec.BorrowStream(nil) 32 defer misc.JSONCodec.ReturnStream(stream) 33 34 stream.WriteVal(obj) 35 defer stream.Flush() 36 if err = stream.Error; err != nil { 37 return 38 } 39 buf := make(JSON, stream.Buffered()) 40 copy(buf, stream.Buffer()) 41 *j = buf 42 return 43 } 44 45 // UnmarshalJSON sets *j to a copy of data. 46 func (j *JSON) UnmarshalJSON(data []byte) error { 47 if j == nil { 48 return errors.New("json: unmarshal json on nil pointer to json") 49 } 50 51 *j = append((*j)[0:0], data...) 52 return nil 53 } 54 55 // MarshalJSON returns j as the JSON encoding of j. 56 func (j JSON) MarshalJSON() ([]byte, error) { 57 return j, nil 58 } 59 60 // Value returns j as a value. 61 // Unmarshal into RawMessage for validation. 62 func (j JSON) Value() (driver.Value, error) { 63 var r json.RawMessage 64 if err := j.Unmarshal(&r); err != nil { 65 return nil, err 66 } 67 68 return []byte(r), nil 69 } 70 71 // Scan stores the src in *j. 72 func (j *JSON) Scan(src any) error { 73 var source []byte 74 75 switch src.(type) { 76 case string: 77 source = []byte(src.(string)) 78 case []byte: 79 source = src.([]byte) 80 default: 81 return errors.New("incompatible type for json") 82 } 83 84 *j = JSON(append((*j)[0:0], source...)) 85 86 return nil 87 }