deserialize values to user-specified unit type
robfitzgerald opened this issue · 1 comments
hi there! thanks for your work.
i want to use uom in code that reads CSVs of velocity data from a user and builds lookup functions from it. i would like to allow the user to specify their velocity unit, but via system configuration instead of inline with every CSV cell, i.e.:
pub fb build_lookup(filename: String, velocity_type: ?) -> {
...
for row in file {
let vel: Velocity<?> = Velocity::try_from(velocity_type, row.velocity)?;
...
}
}
i didn't find any documentation on use of serde with this package to show me how the Type might be parameterized at deserialization, and i did find issues that imply that Units aren't actually reified into enums or structs here to allow matching. i didn't find a function to do this automagically. i tried to build my own enums, which means i have to duplicate the list of supported velocity types, but then i ran into the problem that the return type of my as_quantity
method below would need to return a specific type argument:
#[derive(Debug, Serialize, Deserialize)]
pub enum VelocityType {
MetersPerSecond,
KilometersPerHour,
MilesPerHour,
}
impl VelocityType {
pub fn as_quantity(&self, value: f64) -> Velocity<?> {
match self {
MetersPerSecond -> Velocity::new<meters_per_second>(value),
...
}
}
}
wondering if i missed a way to get this kind of behavior, or if using uom i need to 1) require all users specify velocity in one type such as Velocity<kilometers_per_hour>, 2) require users to append the unit type to every velocity entry in the CSV ("40.2 kph", "41.52 kph" for 55 million rows).
thank you for reading!
You're right that uom
doesn't include units during (de)serialization and because of the generic requirements on fn new
constructing a quantity with a run-time provided unit is not ideal right now. Long term I want to address this issue. Short-term I see a few options, none which are very ideal.
- Include the unit in your file as you mentioned. That's a lot of wasted bytes, but likely the easiest solution.
- Concatenate the configuration-supplied unit with the value before parsing. That's lots of string concatenation, but you save file size.
- Write a custom parsing function similar to the
from_str
impl where the unit is provided as a parameter. You would need to manually write out thematch
expression but would get the best performance/smallest file.
Lines 434 to 445 in 787272d