I am trying to read a range as json but I am seeing an issue while I do json.unmarshal.
here is a test code-
import (
"encoding/json"
"testing"
"github.com/jackc/pgtype"
"github.com/stretchr/testify/assert"
)
type TestHealthPreference struct {
HealthRange pgtype.Int4range `json:"health_range"`
ID string `json:"id"`
}
// just a test to make sure unmarshaling works
func TestPreferenceUpdateUnmarshal(t *testing.T) {
jsonData := `{
"health_range": "[20,30)",
"id": "123"
}`
var update TestHealthPreference
err := json.Unmarshal([]byte(jsonData), &update)
if err != nil {
t.Errorf("Error while unmarshalling JSON: %v", err)
}
assert.Equal(t, 20, update.HealthRange.Lower)
}
Error-
Error while unmarshalling JSON: json: cannot unmarshal string into Go struct field TestPreference.health_range of type pgtype.Int4range.
Is it even possible to read it as pgtype.Int4range? I am guessing this type is for database use only? fwiw, I am using pgx github.com/jackc/pgx/v4
It does not work because "[20,30)"
is not a valid JSON value for the struct pgtype.Int4range
, and pgtype.Int4range hasn't implemented the json.Unmarshaler interface.
You have to implement the interface yourself to unmarshal "[20,30)"
:
type myInt4range pgtype.Int4range
func (r *myInt4range) UnmarshalJSON(b []byte) error {
return (*pgtype.Int4range)(r).DecodeText(nil, bytes.Trim(b, `"`))
}
BTW
assert.Equal(t, 20, update.HealthRange.Lower)
compares two different types, which should be corrected as:
assert.Equal(t, int32(20), update.HealthRange.Lower.Int)
See the full demo here: https://go.dev/play/p/gGNj3kOBB8k.