json.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package types
  2. import (
  3. "database/sql/driver"
  4. "encoding/json"
  5. "errors"
  6. )
  7. // JSONText is a json.RawMessage, which is a []byte underneath.
  8. // Value() validates the json format in the source, and returns an error if
  9. // the json is not valid. Scan does no validation. JSONText additionally
  10. // implements `Unmarshal`, which unmarshals the json within to an interface{}
  11. type JSONText json.RawMessage
  12. var emptyJSON = JSONText("{}")
  13. // MarshalJSON returns the *j as the JSON encoding of j.
  14. func (j JSONText) MarshalJSON() ([]byte, error) {
  15. if len(j) == 0 {
  16. return emptyJSON, nil
  17. }
  18. return j, nil
  19. }
  20. // UnmarshalJSON sets *j to a copy of data
  21. func (j *JSONText) UnmarshalJSON(data []byte) error {
  22. if j == nil {
  23. return errors.New("JSONText: UnmarshalJSON on nil pointer")
  24. }
  25. *j = append((*j)[0:0], data...)
  26. return nil
  27. }
  28. // Value returns j as a value. This does a validating unmarshal into another
  29. // RawMessage. If j is invalid json, it returns an error.
  30. func (j JSONText) Value() (driver.Value, error) {
  31. var m json.RawMessage
  32. var err = j.Unmarshal(&m)
  33. if err != nil {
  34. return []byte{}, err
  35. }
  36. return []byte(j), nil
  37. }
  38. // Scan stores the src in *j. No validation is done.
  39. func (j *JSONText) Scan(src interface{}) error {
  40. var source []byte
  41. switch t := src.(type) {
  42. case string:
  43. source = []byte(t)
  44. case []byte:
  45. if len(t) == 0 {
  46. source = emptyJSON
  47. } else {
  48. source = t
  49. }
  50. case nil:
  51. *j = emptyJSON
  52. default:
  53. return errors.New("Incompatible type for JSONText")
  54. }
  55. *j = JSONText(append((*j)[0:0], source...))
  56. return nil
  57. }
  58. // Unmarshal unmarshal's the json in j to v, as in json.Unmarshal.
  59. func (j *JSONText) Unmarshal(v interface{}) error {
  60. if len(*j) == 0 {
  61. *j = emptyJSON
  62. }
  63. return json.Unmarshal([]byte(*j), v)
  64. }
  65. // String supports pretty printing for JSONText types.
  66. func (j JSONText) String() string {
  67. return string(j)
  68. }
  69. // NullJSONText represents a JSONText that may be null.
  70. // NullJSONText implements the scanner interface so
  71. // it can be used as a scan destination, similar to NullString.
  72. type NullJSONText struct {
  73. JSONText
  74. Valid bool // Valid is true if JSONText is not NULL
  75. }
  76. // Scan implements the Scanner interface.
  77. func (n *NullJSONText) Scan(value interface{}) error {
  78. if value == nil {
  79. n.JSONText, n.Valid = emptyJSON, false
  80. return nil
  81. }
  82. n.Valid = true
  83. return n.JSONText.Scan(value)
  84. }
  85. // Value implements the driver Valuer interface.
  86. func (n NullJSONText) Value() (driver.Value, error) {
  87. if !n.Valid {
  88. return nil, nil
  89. }
  90. return n.JSONText.Value()
  91. }