null_float64.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package xorm
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math"
  6. "reflect"
  7. "strconv"
  8. )
  9. type NullFloat64 struct {
  10. Float64 float64
  11. Valid bool
  12. }
  13. func (nf NullFloat64) Ptr() *float64 {
  14. if !nf.Valid {
  15. return nil
  16. }
  17. return &nf.Float64
  18. }
  19. func (nf NullFloat64) ValueOrZero() float64 {
  20. if !nf.Valid {
  21. return 0
  22. }
  23. return nf.Float64
  24. }
  25. func (nf NullFloat64) IsNil() bool {
  26. return !nf.Valid
  27. }
  28. func (nf *NullFloat64) UnmarshalJSON(data []byte) error {
  29. var err error
  30. var v interface{}
  31. if err = json.Unmarshal(data, &v); err != nil {
  32. return err
  33. }
  34. switch x := v.(type) {
  35. case float64:
  36. nf.Float64 = float64(x)
  37. case string:
  38. str := string(x)
  39. if len(str) == 0 {
  40. nf.Valid = false
  41. return nil
  42. }
  43. nf.Float64, err = strconv.ParseFloat(str, 64)
  44. case map[string]interface{}:
  45. err = json.Unmarshal(data, &nf)
  46. case nil:
  47. nf.Valid = false
  48. return nil
  49. default:
  50. err = fmt.Errorf("json: cannot unmarshal %v into Go value of type xorm.NullFloat64", reflect.TypeOf(v).Name())
  51. }
  52. nf.Valid = err == nil
  53. return err
  54. }
  55. func (nf *NullFloat64) UnmarshalText(text []byte) error {
  56. str := string(text)
  57. if str == "" || str == "null" {
  58. nf.Valid = false
  59. return nil
  60. }
  61. var err error
  62. nf.Float64, err = strconv.ParseFloat(string(text), 64)
  63. nf.Valid = err == nil
  64. return err
  65. }
  66. func (nf NullFloat64) MarshalJSON() ([]byte, error) {
  67. if !nf.Valid {
  68. return []byte("null"), nil
  69. }
  70. if math.IsInf(nf.Float64, 0) || math.IsNaN(nf.Float64) {
  71. return nil, &json.UnsupportedValueError{
  72. Value: reflect.ValueOf(nf.Float64),
  73. Str: strconv.FormatFloat(nf.Float64, 'g', -1, 64),
  74. }
  75. }
  76. return []byte(strconv.FormatFloat(nf.Float64, 'f', -1, 64)), nil
  77. }
  78. func (nf NullFloat64) MarshalText() ([]byte, error) {
  79. if !nf.Valid {
  80. return []byte{}, nil
  81. }
  82. return []byte(strconv.FormatFloat(nf.Float64, 'f', -1, 64)), nil
  83. }