Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to convert <T as funty::Numeric>::Bytes to Vec<u8>? #8

Open
jBernavaPrah opened this issue May 18, 2024 · 1 comment · May be fixed by #10
Open

How to convert <T as funty::Numeric>::Bytes to Vec<u8>? #8

jBernavaPrah opened this issue May 18, 2024 · 1 comment · May be fixed by #10

Comments

@jBernavaPrah
Copy link

Hi!
Thanks a lot for your effort on the crate!

I have difficulties understanding how to use the funty::Numeric or funty::Fondumental trait in my crate. This is for sure because of my lack of knowledge of Rust, I'm still learning it.

Little background

I'm creating an audio crate, and some functions accept a Numeric value (a Sample) that could be f32, u8, i16 etc. I don't care what type of value is passed, I need only to be sure is a numeric value, so I can convert it to a Vec of little-endian.

Problem

I cannot convert the <T as funty::Numeric>::Bytes, returned by .to_le_bytes() function to Vec<u8>.

Process

So my first intuition was to declare a new trait using this syntax:

pub trait Sample: funty::Numeric {}
impl Sample for u8 {}
impl Sample for u16 {}
impl Sample for u32 {}
impl Sample for u64 {}
impl Sample for u128 {}
impl Sample for usize {}
impl Sample for i8 {}
impl Sample for i16 {}
impl Sample for i32 {}
impl Sample for i64 {}
impl Sample for i128 {}
impl Sample for isize {}
impl Sample for f32 {}
impl Sample for f64 {}

And, if I understand Rust correctly, I can create functions in this way:

pub fn use_sample<T: Sample>(sample: T)  {
   sample.to_le_bytes()
}

// and this function can be called any combination: 
// use_sample(3) or use_sample(0.1233123)
println!("Result: {:?}", use_sample(3 as u8)) // Result: [3]
println!("Result: {:?}", use_sample(0.1233123)) // Result: [109, 205, 177, 23, 101, 145, 191, 63] 

My problem starts now. I'm not able to use the funty::Bytes (<T as funty::Numeric>::Bytes) returned by to_le_bytes function.

What I need is the possibility to do the following:

pub fn use_sample<T: Sample>(sample: T) -> Vec<u8> {
   sample.to_le_bytes().to_vec()
}

But the error triggered is:

sample.to_le_bytes().to_vec()
                                    ^^^^^^ method not found in `<T as Numeric>::Bytes`

So, after this introduction, the real question is:
how can I convert <T as Numeric>::Bytes into Vec<u8>?

@jBernavaPrah jBernavaPrah changed the title How to use it? How to convert <T as funty::Numeric>::Bytes to Vec<u8>? May 18, 2024
@tyilo
Copy link

tyilo commented Jun 4, 2024

I have had a similar need in my own code.

You can create an extension trait for Numeric which you can easily implement for all the types using a macro:

use funty::Numeric;

trait NumericExt: Numeric {
    fn to_le_bytes_boxed(self) -> Box<[u8]>;
}

macro_rules! impl_numeric_ext {
    ($name:ty) => {
        impl NumericExt for $name {
            fn to_le_bytes_boxed(self) -> Box<[u8]> {
                Box::new(self.to_le_bytes())
            }
        }
    }
}

impl_numeric_ext!(u8);
impl_numeric_ext!(u16);
impl_numeric_ext!(u32);
impl_numeric_ext!(u64);
impl_numeric_ext!(u128);
impl_numeric_ext!(usize);
impl_numeric_ext!(i8);
impl_numeric_ext!(i16);
impl_numeric_ext!(i32);
impl_numeric_ext!(i64);
impl_numeric_ext!(i128);
impl_numeric_ext!(isize);
impl_numeric_ext!(f32);
impl_numeric_ext!(f64);

fn print_bytes<T: NumericExt>(v: T) {
    let bytes = v.to_le_bytes_boxed();
    println!("{:?}", bytes);
}

fn main() {
    print_bytes(123u8);
    print_bytes(123u32);
}

@tyilo tyilo linked a pull request Jun 4, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants