1

I have the following code:

pub fn get_value_as_double_at_index(&self, x: u32, y: u32, z: u32, t: u32) -> f64 {
    use ChannelDataType::*;
    let channel_data = &self.channel_data[t as usize];
    let index = 1;
    // panic!("oops");
    return match channel_data.data_type {
        BYTE => channel_data.get_data::<u8>()[index] as f64,
        SHORT => channel_data.get_data::<u16>()[index] as f64,
        INT => channel_data.get_data::<u32>()[index] as f64,
        FLOAT => channel_data.get_data::<f64>()[index] as f64,
        _ => -1.0,
    };
}

I want to convert it to a generic. I found How to convert generic primitive types in Rust? and tried to replicate it but I get a compilation error.

Here's my minimally reproducible example (playground):

extern crate num; // 0.2.1
use num::cast::AsPrimitive;
use num::Num;

fn get_data<T: num::Zero + Num + Sized>() -> [T; 1] {
    [T::zero()]
}

fn get_value_at_index<T>(output_type: u8, index: usize) -> T
where
    T: num::cast::AsPrimitive<T> + Num + Sized,
{
    match output_type {
        0 => get_data::<u8>()[0].as_(),
        1 => get_data::<u16>()[0].as_(),
        _ => panic!("not handled in playground"),
    }
}

I get these errors:

error[E0277]: the trait bound `u8: num::traits::AsPrimitive<T>` is not satisfied
  --> src/lib.rs:14:34
   |
14 |         0 => get_data::<u8>()[0].as_(),
   |                                  ^^^ the trait `num::traits::AsPrimitive<T>` is not implemented for `u8`

error[E0277]: the trait bound `u16: num::traits::AsPrimitive<T>` is not satisfied
  --> src/lib.rs:15:35
   |
15 |         1 => get_data::<u16>()[0].as_(),
   |                                   ^^^ the trait `num::traits::AsPrimitive<T>` is not implemented for `u16`

What am I doing wrong?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
thejinx0r
  • 444
  • 7
  • 10
  • Your question might be answered by the answers of [Is there any trait that specifies numeric functionality?](https://stackoverflow.com/q/37296351/155423); [How do I use integer number literals when using generic types?](https://stackoverflow.com/q/28565440/155423); [How do I use floating point number literals when using generic types?](https://stackoverflow.com/q/50767912/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Apr 07 '20 at 15:25
  • 1
    Don't you want `u8: AsPrimitive + Num + Sized`? – Shepmaster Apr 07 '20 at 15:41
  • @shepmaster sorry, I had hit save edit to early and didn't realize that you would be notfied. The code that I had originally should what I wanted to do, but the original playground code produced the error and now I have made the playground produce the error and has the spirit of what I'm trying to achieve. – thejinx0r Apr 07 '20 at 15:50
  • 1
    *``the trait bound `u8: num::traits::AsPrimitive` is not satisfied``* — you need to require those bounds. [example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=abd9a458061af18ca3728fff363a5de1) – Shepmaster Apr 07 '20 at 16:02
  • @Shepmaster Can you post it an answer? I didn't know that you had to add it manually in to the type requirement. I had assumed that by using "use num::cast::AsPrimitive;" it would be auto-implemented by the compiler, but I was wrong. I never came across that syntax before and assumed that you meant replace T with u8, not that I needed to have both. Thanks for that! – thejinx0r Apr 07 '20 at 16:08

0 Answers0