-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[http] Strange behaviour around sending reference types #72
Comments
unexported fields can't be json marshaled. Other packages can't read fields of your struct if you don't give them that ability. |
That explains case 2, but what about case 1, float vs big.Int? |
I don't know what youre expecting to happen. What types does json have? If you don't tell the commands lib what type to use, youre going to get json types. json has floats, json doesnt have 'big integers' |
@dignifiedquire your struct |
Yeah, I got that, but it is super surprising and not at all clear that a json encoder is used from the current docs :/ |
also the first issue still is there, cmds lib shouldn't freak out on a bigInt when getting a float just because json is unable to represent that properly |
@dignifiedquire use your brain. a big int encodes to json as a float. Then, without telling the commands lib how to intepret whatever response it gets, you just generically try to decode the thing. So the json unmarshaler, without any type hints, says "this is a float" and decodes it as such. This is the whole reason we have the type field on the commands. |
I understand the reason but I think the library should do better and allow the conversion from float to bigint automatically or use a better encoder that encodes bigints as string with enough information to get them back exactly.
…On 17. Mar 2018, 19:51 +0100, Whyrusleeping ***@***.***>, wrote:
@dignifiedquire use your brain. a big int encodes to json as a float. Then, without telling the commands lib how to intepret whatever response it gets, you just generically try to decode the thing. So the json unmarshaler, without any type hints, says "this is a float" and decodes it as such.
This is the whole reason we have the type field on the commands.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Ideally, we'd be using CBOR or something but we'd need to add support for that. |
@dignifiedquire I don't think youre understanding this here. The explicit contract of the library is "SET THE TYPE ON THE COMMAND". I guess we could check to see if its unset and do |
@whyrusleeping @dignifiedquire Actually JSON doesn't use floats but Numbers, and big.Int implements json.Marshaler and json.Unmarshaler so you can actually do it that way if you expect big.Int. It's just that Go parses JSON Numbers into float64 if no type indication is given. type Result struct {
Int *big.Int
Cid *cid.Cid
isInt bool // to decide which one is used
}
func (r *Result) JSONMarshal() ([]byte, error) {
if r.isInt {
return json.Marshal(r.Int)
} else {
return json.Marshal(r.Cid)
}
}
func (r *Result) JSONUnmarshal(data []byte) error {
if data[0] >= '0' && data[0] <= '9' {
r.isInt = true
r.Int = big.NewInt(0)
return json.Unmarshal(data, r.Int)
} else {
r.isInt = false
r.Cid = cid.NewCid() // or sth like that
return json.Unmarshal(data, r.Cid)
}
} |
I am trying to implement a command which has Type either
*big.Int
orbig.Cid
.Type
and onlyMakeEncoder
and sendbig.NewInt(0)
I end up with the errorunexpected type float64 (expected interface {})
and use
Type: &result{}
, I end up with result being nil when sendingresult{myint: big.NewInt(0)}
The text was updated successfully, but these errors were encountered: