Skip to content

Commit d3fb6e0

Browse files
KirillMironovjackc
authored andcommitted
implement json.Marshaler and json.Unmarshaler for Float4, Float8
1 parent cf6ef75 commit d3fb6e0

File tree

4 files changed

+129
-7
lines changed

4 files changed

+129
-7
lines changed

pgtype/float4.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package pgtype
33
import (
44
"database/sql/driver"
55
"encoding/binary"
6+
"encoding/json"
67
"fmt"
78
"math"
89
"strconv"
@@ -65,6 +66,29 @@ func (f Float4) Value() (driver.Value, error) {
6566
return float64(f.Float32), nil
6667
}
6768

69+
func (f Float4) MarshalJSON() ([]byte, error) {
70+
if !f.Valid {
71+
return []byte("null"), nil
72+
}
73+
return json.Marshal(f.Float32)
74+
}
75+
76+
func (f *Float4) UnmarshalJSON(b []byte) error {
77+
var n *float32
78+
err := json.Unmarshal(b, &n)
79+
if err != nil {
80+
return err
81+
}
82+
83+
if n == nil {
84+
*f = Float4{}
85+
} else {
86+
*f = Float4{Float32: *n, Valid: true}
87+
}
88+
89+
return nil
90+
}
91+
6892
type Float4Codec struct{}
6993

7094
func (Float4Codec) FormatSupported(format int16) bool {

pgtype/float4_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,44 @@ func TestFloat4Codec(t *testing.T) {
2121
{nil, new(*float32), isExpectedEq((*float32)(nil))},
2222
})
2323
}
24+
25+
func TestFloat4MarshalJSON(t *testing.T) {
26+
successfulTests := []struct {
27+
source pgtype.Float4
28+
result string
29+
}{
30+
{source: pgtype.Float4{Float32: 0}, result: "null"},
31+
{source: pgtype.Float4{Float32: 1.23, Valid: true}, result: "1.23"},
32+
}
33+
for i, tt := range successfulTests {
34+
r, err := tt.source.MarshalJSON()
35+
if err != nil {
36+
t.Errorf("%d: %v", i, err)
37+
}
38+
39+
if string(r) != tt.result {
40+
t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, string(r))
41+
}
42+
}
43+
}
44+
45+
func TestFloat4UnmarshalJSON(t *testing.T) {
46+
successfulTests := []struct {
47+
source string
48+
result pgtype.Float4
49+
}{
50+
{source: "null", result: pgtype.Float4{Float32: 0}},
51+
{source: "1.23", result: pgtype.Float4{Float32: 1.23, Valid: true}},
52+
}
53+
for i, tt := range successfulTests {
54+
var r pgtype.Float4
55+
err := r.UnmarshalJSON([]byte(tt.source))
56+
if err != nil {
57+
t.Errorf("%d: %v", i, err)
58+
}
59+
60+
if r != tt.result {
61+
t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
62+
}
63+
}
64+
}

pgtype/float8.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,29 @@ func (f Float8) Value() (driver.Value, error) {
7474
return f.Float64, nil
7575
}
7676

77+
func (f Float8) MarshalJSON() ([]byte, error) {
78+
if !f.Valid {
79+
return []byte("null"), nil
80+
}
81+
return json.Marshal(f.Float64)
82+
}
83+
84+
func (f *Float8) UnmarshalJSON(b []byte) error {
85+
var n *float64
86+
err := json.Unmarshal(b, &n)
87+
if err != nil {
88+
return err
89+
}
90+
91+
if n == nil {
92+
*f = Float8{}
93+
} else {
94+
*f = Float8{Float64: *n, Valid: true}
95+
}
96+
97+
return nil
98+
}
99+
77100
type Float8Codec struct{}
78101

79102
func (Float8Codec) FormatSupported(format int16) bool {
@@ -109,13 +132,6 @@ func (Float8Codec) PlanEncode(m *Map, oid uint32, format int16, value any) Encod
109132
return nil
110133
}
111134

112-
func (f *Float8) MarshalJSON() ([]byte, error) {
113-
if !f.Valid {
114-
return []byte("null"), nil
115-
}
116-
return json.Marshal(f.Float64)
117-
}
118-
119135
type encodePlanFloat8CodecBinaryFloat64 struct{}
120136

121137
func (encodePlanFloat8CodecBinaryFloat64) Encode(value any, buf []byte) (newBuf []byte, err error) {

pgtype/float8_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,44 @@ func TestFloat8Codec(t *testing.T) {
2121
{nil, new(*float64), isExpectedEq((*float64)(nil))},
2222
})
2323
}
24+
25+
func TestFloat8MarshalJSON(t *testing.T) {
26+
successfulTests := []struct {
27+
source pgtype.Float8
28+
result string
29+
}{
30+
{source: pgtype.Float8{Float64: 0}, result: "null"},
31+
{source: pgtype.Float8{Float64: 1.23, Valid: true}, result: "1.23"},
32+
}
33+
for i, tt := range successfulTests {
34+
r, err := tt.source.MarshalJSON()
35+
if err != nil {
36+
t.Errorf("%d: %v", i, err)
37+
}
38+
39+
if string(r) != tt.result {
40+
t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, string(r))
41+
}
42+
}
43+
}
44+
45+
func TestFloat8UnmarshalJSON(t *testing.T) {
46+
successfulTests := []struct {
47+
source string
48+
result pgtype.Float8
49+
}{
50+
{source: "null", result: pgtype.Float8{Float64: 0}},
51+
{source: "1.23", result: pgtype.Float8{Float64: 1.23, Valid: true}},
52+
}
53+
for i, tt := range successfulTests {
54+
var r pgtype.Float8
55+
err := r.UnmarshalJSON([]byte(tt.source))
56+
if err != nil {
57+
t.Errorf("%d: %v", i, err)
58+
}
59+
60+
if r != tt.result {
61+
t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)