[Feature] Deserializer: Set Default Numeric Type
Opened this issue · 1 comments
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
.
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?