uom icon indicating copy to clipboard operation
uom copied to clipboard

Unclear about how to create arbitrary quantities with arbitrary units

Open joe-saronic opened this issue 4 months ago • 6 comments

I'm new to rust and very new to UOM, so admittedly, this is likely user error caused by a lack of understanding. This is a followup from my StackOverflow post, which got no traction unfortunately.

I am trying to make a simple type that will be backed by an array in the default units of a given dimension. The idea is pretty simple: I provide a constructor that converts quantities to base units and getters that convert them back to desired units for some given dimension:

use anyhow::Result;
use core::marker::PhantomData;
use uom::{
    Conversion, si::{Dimension, Quantity, SI, Unit, length::{Dimension as Length, meter}},
};

#[derive(Debug)]
struct Coordinate<D: Dimension + ?Sized> {
    buf: [f64; 2],
    dim: PhantomData<D>,
}

impl<D: Dimension + ?Sized> Coordinate<D>
{
    pub fn new<U: Unit + Conversion<f64>>(x: f64, y: f64) -> Self {
        Self {
            buf: [
                Quantity::<D, SI<f64>, f64>::new::<U>(x).value,
                Quantity::<D, SI<f64>, f64>::new::<U>(y).value,
            ],
            dim: PhantomData,
        }
    }

    pub fn x(&self) -> Quantity<D, SI<f64>, f64> {
        Quantity::<D, SI<f64>, f64> { dimension: PhantomData, units: PhantomData, value: self.buf[0], }
    }

    pub fn y(&self) -> Quantity<D, SI<f64>, f64> {
        Quantity::<D, SI<f64>, f64> { dimension: PhantomData, units: PhantomData, value: self.buf[1], }
    }
}

fn main() -> Result<()> {
    let n = Coordinate::<Length>::new::<meter>(1.0, 1.0);
    println!("{n:?}");
    Ok(())
}

I end up with a couple of different errors that I can't quite make sense of:

   Compiling scratchpad v0.1.0 (/home/joe/saronic/scratch/scratchpad)
error[E0599]: no function or associated item named `new` found for struct `Quantity<D, ..., ...>` in the current scope
  --> src/main.rs:18:46
   |
18 |                 Quantity::<D, SI<f64>, f64>::new::<U>(x).value,
   |                                              ^^^ function or associated item not found in `Quantity<D, ..., ...>`
   |
   = note: the full type name has been written to '/home/joe/saronic/scratch/scratchpad/target/debug/deps/scratchpad-dd83b867192bd049.long-type-8409603177462832417.txt'
   = note: the function or associated item was found for
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = PInt<UInt<UTerm, B1>>, Th = Z0> + 'static), U, V>`
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = NInt<UInt<UInt<UTerm, B1>, B0>>, Th = Z0> + 'static), U, V>`
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UInt<UTerm, B1>, B0>>, M = PInt<UInt<UTerm, B1>>, N = Z0, T = NInt<UInt<UTerm, B1>>, Th = Z0> + 'static), U, V>`
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = Z0, M = Z0, N = PInt<UInt<UTerm, B1>>, T = Z0, Th = Z0> + 'static), U, V>`
           and 106 more types

error[E0599]: no function or associated item named `new` found for struct `Quantity<D, ..., ...>` in the current scope
  --> src/main.rs:19:46
   |
19 |                 Quantity::<D, SI<f64>, f64>::new::<U>(y).value,
   |                                              ^^^ function or associated item not found in `Quantity<D, ..., ...>`
   |
   = note: the full type name has been written to '/home/joe/saronic/scratch/scratchpad/target/debug/deps/scratchpad-dd83b867192bd049.long-type-8409603177462832417.txt'
   = note: the function or associated item was found for
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = PInt<UInt<UTerm, B1>>, Th = Z0> + 'static), U, V>`
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = NInt<UInt<UInt<UTerm, B1>, B0>>, Th = Z0> + 'static), U, V>`
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UInt<UTerm, B1>, B0>>, M = PInt<UInt<UTerm, B1>>, N = Z0, T = NInt<UInt<UTerm, B1>>, Th = Z0> + 'static), U, V>`
           - `Quantity<(dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = Z0, M = Z0, N = PInt<UInt<UTerm, B1>>, T = Z0, Th = Z0> + 'static), U, V>`
           and 106 more types

error[E0277]: `dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = Z0, Th = Z0>` doesn't implement `Debug`
  --> src/main.rs:36:15
   |
36 |     println!("{n:?}");
   |               ^^^^^ `dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = Z0, Th = Z0>` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
   = help: the trait `Debug` is not implemented for `dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = Z0, Th = Z0>`
   = help: the following other types implement trait `Debug`:
             (dyn Any + 'static)
             (dyn Any + Send + 'static)
             (dyn Any + Send + Sync + 'static)
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `scratchpad` (bin "scratchpad") due to 3 previous errors

I am having trouble understanding what is going on here because I was under the impression that there is a blanket implementation of new for Quantity, but apparently that's not the case.

If I comment out the lines with Quantity::<D, SI<f64>, f64>::new::<U>(...).value,, e.g. like 0.0, //Quantity::<D, SI<f64>, f64>::new::<U>(x).value,, the debug error still persists:

   Compiling scratchpad v0.1.0 (/home/joe/saronic/scratch/scratchpad)
error[E0277]: `dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = Z0, Th = Z0>` doesn't implement `Debug`
  --> src/main.rs:36:15
   |
36 |     println!("{n:?}");
   |               ^^^^^ `dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = Z0, Th = Z0>` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
   = help: the trait `Debug` is not implemented for `dyn Dimension<I = Z0, J = Z0, Kind = (dyn Kind + 'static), L = PInt<UInt<UTerm, B1>>, M = Z0, N = Z0, T = Z0, Th = Z0>`
   = help: the following other types implement trait `Debug`:
             (dyn Any + 'static)
             (dyn Any + Send + 'static)
             (dyn Any + Send + Sync + 'static)
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `scratchpad` (bin "scratchpad") due to previous error

I have had a hard time finding a good tutorial for UOM. My issue is that while the crate is well documented and thorough, it appears to assume a certain level of prior knowledge that I simply don't have.

joe-saronic avatar Mar 04 '24 15:03 joe-saronic