-
Notifications
You must be signed in to change notification settings - Fork 144
RUST-882 Remove lossy From<u64>
impl for Bson
#280
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
RUST-882 Remove lossy From<u64>
impl for Bson
#280
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
In the lack of concrete requests, I think it's fine to not have a TryFrom
implementation; if we do need to add one, I'd lean towards reusing <i64 as TryFrom<u64>>::Error
for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, agree w/ Abraham on holding off until someone requests the TryFrom
functionality
This reverts commit 88ae843.
As this broke my code, I have a question: why? What data loss happened with the |
What the rustnomicon means by no-op is that the bits themselves aren't changed as part of the cast since they all still fit in the new integer type; however, when switching from a signed integer to an unsigned one, the interpretation of those bits does change now that one of them is reserved for the sign bit. The issue is that there are values of e.g. in let myval: u64 = i64::MAX as u64 + 10;
println!("{}", myval);
let doc = doc! {
"u64": myval
};
println!("{}", doc); And it would print: 9223372036854775817
{ "u64": -9223372036854775799 } Note that for this same reason, the standard library only implements Hope this helps, and please let us know if you have any further questions! |
I understand the theory behind the decision, but I'm approaching from the UX side: this change just makes using unsigned ints annoying. All I want to do is serialize a u64, I don't really care about the underlying representation. Normally I'd assume the u2i feature handles anything required. The readme states the following: "Any types that implement Serialize and Deserialize can be used in this way." This is unfortunately not true due to restrictions like in this PR. A lossy operation means loss of information. In case of unsigned - signed conversion, if the types are of the same size, there is no loss of information, only a change in interpretation. This means, that even if the intermediate bson representation wraps my |
Good point; I filed RUST-968 to discuss with the team the possibility of enabling
The bits aren't being lost sure, but the type information certainly is. The database, the shell, other tools, etc. can't know the value is unsigned-but-stored-as-signed while the original Rust application did. For example, this means queries based on ordering (e.g. |
This is an excellent point and an oversight on my end, for sure.
I guess this is fair enough. A bit uncomfortable, but not impossible. Thanks! |
No problem, and don't hesitate to reach out if you have any further questions! |
RUST-882
This PR removes the
From<u64>
impl forBson
that could be lossy in the event that theu64 > i64::MAX
. I opted to not replace it with aTryFrom
implementation as I would have to specify an error, and I wasn't sure if we wanted to create yet another error type just for this case. An alternative could be to use<i64 as TryFrom<u64>>::Error
, but I wasn't sure if that would be weird. Let me know what you guys think.The lossiness in
From<u32>
was fixed in #276.