Function definition with generic struct

how to create a function that accepts multiple types of structs.

i have mod1.rs and main.rs.
function in mod.rs can be called by multiple places so I can't hardcode struct in mod.rs.

i want to pass struct while calling like

mod mod1;

strcut Person {
name: String,
}

fn main(){
let person_1 = Person{name: String::from("manny"};
mod1::run(p: person_1);
}

what should be fn run() definition in mod1.rs so that type is not hardcoded and accepts multips type structs.

Look into traits. You can define a trait and then impl it on all the types you want the function to handle. You can then update your function to accept any type which implements the defined trait instead of a specific type.

Read more about traits and using them here (has examples too).

5 Likes

yes i can use trait. One thing i don't understand is, the struct im talking about is just stores output from sql query and returns. I don't have need of any method to implement on this struct type.
still i can use trait. or any other way.

Rust doesn't knows how and why you are using fields. If the run function will only work with Strings you may prefer using Into<String> as parameter type and implement From<Person> for String. If this is not the case you have to define a new trait and implement the logic for every struct you will use with run.

2 Likes

Well, just what are you trying to do? Why do you think you need your function to accept multiple types?

The whole point of traits is that they specify what you can do with a generic type. What common capabilities does your function need in order to work? If there are none, e.g. it just moves stuff around in memory, you probably don't need any trait bounds. But that's rare.

It's also possible that you always want a specific type, in which case I don't understand the question.

1 Like

thanks for your time.

the way i want to design is, my main.rs uses sql client, so i separated as a module i.e sql_client.rs
now you all helped me understand that i have to use trait and impl on all the data type i want to pass it to sql module.

One last question before i mark this a close.
if define a struct in main.rs and pass it to sql module, then i get error saying struct is not in the scope.
i know how to call exported modules in main, but how can i use the struct use a struct in sql_client.rs which is defined in main.rs.

reason i separated is , my module takes two parameters, one is sql query as string and struct. because query and struct may vary.

does this design make sense.

thank you.

you are right, my module takes query as a string, and struct.
execute query
create a vector of structs
return vector.

i don't need any function to be executed on the struct.

I don't think you can. You would usually do the opposite, i.e. use in main what you defined in another module.

If you really do need your type in another module, create a third module that you import from main as well.

1 Like

Your struct seems logically relevant to the functions in sql_client.rs module, I think you should define it there. You can easly import it in the main.rs and use.

I am able to define Struct in main.rs and use crate::Struct in sql.rs?

2 Likes

I might be wrong – still wouldn't recommend it.

1 Like

it's possible and worked for me, i'm not sure if it's right.

i agree with you but my let me explain the problem. sql_client module takes query string, so im using 10 different queries, have to add new struct to sql_client module each time i write new query in main.rs.

so i'm trying to find right approch.

I don't really understand. You are saying that functions in sql_client takes a String as parameter and you have to create a new struct for every query. Why? Can you share the code?

Then you should put structs and queies in the same module.

here is the code. run in sql_client.rs needs sql query and a struct to store the result.

struct Data{
    name: String,
    age: String,
    sex: String,
}

pub fn run(stm: String, Data: Data) -> Result<(), mysql::Error> {
    let url = "mysql://user:pass@host:3306/db";

    let pool = mysql::Pool::new(url)?;

    let mut conn = pool.get_conn()?;

    let selected_payments = conn.query_map(
        stm,
        |(name, age, sex)| Data {
            name,
            age,
            sex,
        },
    )?;

i tried to retain the format, but somehow it's messed up. sorry about that.

Please read the Forum Code Formatting and Syntax Highlighting that is pinned to the top of this forum, then edit all of your prior posts that contain code by using the edit button under each of those posts.

Many readers of this forum will ignore code snippets that do not follow those posting guidelines. Even those who do respond may feel that the lack of following the forum posting guidelines is disrespectful of their time. Thanks. :clap:

1 Like

Hmm, I don't know how to deal with this kind of API. You may want to look at the crate documentation for examples.

np thank you very much for your time. @eko