Home > other >  Reading a signed value into an unsigned type
Reading a signed value into an unsigned type

Time:10-13

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.

  • Related