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

[Feature] Deserializer: Set Default Numeric Type #520

Open
bbb651 opened this issue Nov 19, 2023 · 1 comment
Open

[Feature] Deserializer: Set Default Numeric Type #520

bbb651 opened this issue Nov 19, 2023 · 1 comment

Comments

@bbb651
Copy link

bbb651 commented Nov 19, 2023

Currently it's possible to specify type suffixes for integers and floats to control what type they serialize to, however, for types without a type suffix the normal behavior of using the smallest numeric type that fits the value.
I would like a way to use a consistent default type for values that specify one, I thought of two ways of achieving that:

  • Adding a field to ron::options::Options to control default numeric types. This could look something like this enum or maybe even be a callback that takes a number and returns the ron value
pub enum DefaultNumericType {
    Smallest,
    Fit(IntType, FloatType), // Error if type doesn't fit
    Minimum(IntType, FloatType), // These types if they fit, or smallest that fits
    Largest,
}
  • Storing numeric type suffix as part of numeric values. This gives the user more control over handling type suffixes but doesn't sound like a great idea: it's more complicated to implement, a massive breaking change and probably less efficient

My use case is using ron as a text format for dbus varients. These are dynamically typed objects that store their types as part of their value, and it makes sense for my use case to default integers to u32 and floats to f64.

@juntyr
Copy link
Member

juntyr commented Nov 20, 2023

I may need some clarification before I'm able to give you a good answer. During serialisation, we always serialise numeric values as-is, and the ron::ser::PrettyConfig::number_suffixes flag can be used to add the type suffix to these values, i.e. serialising a u32 would always produce v_u32 independent of the value v. At deserialise time, when we parse numeric values, we then check for these suffixes. If they do not exist, we indeed interpret the value as belonging to the smallest possible type. If they do, then that is the type we use. Finally, we tell the serde::de::Visitor via its visit_ty (e.g. visit_u32) method that we have seen a value of a specific numeric type. serde's Deserialize implementations for the primitives allow values to be cast to larger or smaller types as long as they are in their range. However, if the ron value had a type suffix and serde hints at us that it is expecting a different numeric value, we do raise an error.

If I understood you correctly, you want to customise the behaviour of how to parse numeric values when we don't have their suffix and are not sure what numeric type they should be, which is the case when using deserialize_any, which e.g. affects how ron::Value is parsed. Is that correct? Would it be possible to handle this at the Deserialize impl side instead, e.g. by having a wrapper that always tries to forward a visit_ty call to the smallest/largest possible one or that only accepts a specific one and errors otherwise?

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

No branches or pull requests

2 participants