iliekturtles / uom

Units of measurement -- type-safe zero-cost dimensional analysis
Apache License 2.0
989 stars 89 forks source link

deserialize values to user-specified unit type #427

Open robfitzgerald opened 1 year ago

robfitzgerald commented 1 year ago

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, 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!

iliekturtles commented 1 year ago

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.

https://github.com/iliekturtles/uom/blob/787272dab89d254d79c430b8b2efff06ab505cab/src/quantity.rs#L434-L445