In Go, one can take a signed value and force the language to interpret it as unsigned by doing something like:
var x int32
var y uint32
x = -1
y = uint32(x)
This works as expected with y
taking the largest unsigned int32 value. However, if I have a JSON string like so:
Note: it doesn't seem to matter if the value -20
is serialized as a string or as a number
jsonStr := `{"RandomNumber: -20}
type DummyJson struct {
RandomNumber uint32
}
rd := &DummyJson{}
err := json.Unmarshal([]byte(jsonStr), &rd)
fmt.Println(err)
Here, it complains the value -20 cannot be unmarshaled into the RandomNumber field. How can I convince Go to shove the signed value into an unsigned type?
P.S: The motivation for doing this is long and convoluted. So please assume there is a legitimate reason behind this question.
CodePudding user response:
Create custom type with UnmarshalJSON
method.
type DummyJson struct {
RandomNumber CustomIntType
}
type CustomIntType uint32
func (ct *CustomIntType) UnmarshalJSON(b []byte) error {
var x int32
var y uint32
s := string(b)
if i, err := strconv.Atoi(s); err == nil {
x = int32(i)
y = uint32(x)
*ct = CustomIntType(y)
} else {
return err
}
return nil
}
jsonStr := `{"RandomNumber": -20}`
var rd DummyJson
err := json.Unmarshal([]byte(jsonStr), &rd)
fmt.Println(rd.RandomNumber, err)
I am sure that the conversion can be optimised, but not sure how.