Skip to content
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

Introduce feature serde_lossy that can deserialize u64, i64, f64 #33

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kosta
Copy link

@kosta kosta commented May 8, 2017

The goal is to be able to deserialize json like {a: 1, b: 2.5} into {a: d128, b: d128} using serde.

I think something "opt-in" is needed, at least for floating point, because serde will parse "numbers with comma" as f64, possibly losing precision. (see my changes to Readme.md)

I'm not 100% sure about this approach, but this works and is opt-in.

You can test this using cargo test --features serde_lossy.

An alternative approach is to expose an alternative visitor and implement visit_f64() etc. for that visitor. That alternative visitor can then be used through #[serde(deserialize_with = ...)]. However that is much more cumbersome, as you'd need to annotate every field with #[serde(deserialize_with = ...)] and I'm not sure how to handle e.g. BTreeMap<String, d128> with that approach.

Let me know what you think. I'm happy to implement different approaches you might prefer.

@kosta
Copy link
Author

kosta commented May 17, 2017

Hi!

Were you able to take a look at this? What do you think?

Cheers,
Kosta

@alkis
Copy link
Owner

alkis commented May 17, 2017 via email

@kosta
Copy link
Author

kosta commented May 18, 2017

No worries, l'll wait for you :)

@alkis
Copy link
Owner

alkis commented Jun 2, 2017

Finally I found some time to take a look. I think this added complexity is not necessary. One can parse numbers in a lossy way by defining two structs: one with int/float and then convert to the struct with d128.

The conversion from integer types to decimal is never lossy, perhaps that we can do anyway? WDYT?

@kosta
Copy link
Author

kosta commented Jun 5, 2017

Yeah I think we can always do integer conversion, the only thing I'm not sure about is whether is violates "principle of least surprise": If I want to deserialize to d128 (which is supports "decimal points"), at first glace I find it odd if I can deserialize {"value": 5} but not {"value": 5.5}. Of course if I know about the serde internals and "lossiness" this makes sense - but it's not intuitive. That's why I hid both behind that feature flag.

I'm not 100% sure though, I guess it's your call :)

I find the "two structs" solution very cumbersome. Would you merge instead: a pub deserialize_lossy() function that can be used with #[serde(deserialize_with=...)]?

@alkis
Copy link
Owner

alkis commented Jun 18, 2017

Can't the user provide a deserialize_with= function on their own? It shouldn't be too hard.

Do you want to add lossless integer conversion?

@alkis
Copy link
Owner

alkis commented Jun 18, 2017

Just some more thoughts on this. When you work with decimal, it is usually because you know floating point does not work for you. So we can assume the user knows they can't represent many decimals with floating point numbers. If they are aware of the issues I think they will understand why we can deserialize "1.4" but not 1.4 and also why we serialize 1.4 into "1.4" and not 1.4. Perhaps all that is necessary here is an FAQ?

@kosta
Copy link
Author

kosta commented Jul 10, 2017

Sorry for the late reply! (I'm on paternal leave atm)

What about the following: Discard this PR and the "lossy" feature.

I can instead implement:

  • Allow deserialization of integers
  • Allow Provide a function you can pass to serde's deserialize_with, e.g. derserialize_lossy. (Yes, such a function is easy to write but there is no need for everyone to write their own)
  • Add a FAQ entry why integers can be deserialized but floating points only more cumbersomely.

Sounds good?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants