Help with generic structs and factory functions

Playground: Rust Playground

I have a generic struct, and want to have a factory function in the impl block with two arguments. However, I get an error

   Compiling playground v0.0.1 (/playground)
error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> src/main.rs:38:19
    |
38  |     let wrapper = module::Wrapper::from(&a, module::Options::A);
    |                   ^^^^^^^^^^^^^^^^^^^^^ --  ------------------ supplied 2 arguments
    |                   |
    |                   expected 1 argument
    |
note: associated function defined here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0061`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

Code:

mod module {
    
    #[derive(Debug, Clone)]
    pub struct Wrapper<'a, T: std::fmt::Display + std::fmt::Debug> {
        options: Options,
        data: &'a T,
    }
    
    impl<'a, T: std::fmt::Display + std::fmt::Debug> Wrapper<'a, T> {
        fn from(data: &'a T, options: Options) -> Self {
            Self{
                data,
                options,
            }
        }
    }
    
    pub fn from2<T: std::fmt::Display + std::fmt::Debug>(data: &T, options: Options) -> Wrapper<T> {
        Wrapper::<T>{
            data,
            options,
        }
    }
    
    #[derive(Debug, Clone)]
    pub enum Options {
        A,
        B,
        C,
    }
}

fn main() {
    let a = 1;
    let wrapper2 = module::from2(&a, module::Options::A);
    println!("{:#?}", wrapper2);
    
    let wrapper = module::Wrapper::from(&a, module::Options::A);
    println!("{:#?}", wrapper);
}

I fail to see why the compiler expects 1 argument

Ah, that's a sneaky one. I tried your playground and was also confused. It turns out you just need to make the from function pub: playground.

When it is private, what happens is that the from function from the From trait, which is a part of the Rust prelude, is the function that it tries to call, and that function only has one argument.

I suspected that that might be what was happening, but I didn't figure out why it was getting confused until I renamed the function to new and it gave a much more meaningul error, saying that the new function was private.

1 Like

thank you very much!!

1 Like