I am trying to share a struct between two files, but I am getting an error.
I have the following folder structure:
src/
Models/
Login.rs
Routes/
LoginRoute.rs
Services/
LoginService.rs
main.rs
In Login.rs
I have:
#[derive(Serialize, Deserialize, Debug)]
pub struct UserLoginResponse {
id: i32,
username: String,
token: String
}
In LoginRoute.rs
I have:
#[path = "../Models/Login.rs"]
pub mod Login;
#[path = "../Services/LoginService.rs"]
pub mod LoginService;
#[post("/login", format = "application/json", data = "<user>")]
pub async fn login(user: String) -> Json<Login::UserLoginResponse> {
if let Ok(sk) = LoginService::callAuthenticate(user).await {
return sk
......
In LoginService.rs
I have:
#[path = "../Models/Login.rs"]
pub mod Login;
pub async fn callAuthenticate(user: String)-> Result<Json<Login::UserLoginResponse>, Error> {
...
let userLoginResponse :Login::UserLoginResponse = Login::UserLoginResponse::new(1, "admin".to_string(), api_reponse.return_result);
Ok(Json(userLoginResponse))
}
I am getting error in LoginRoute.rs
on the return sk
line:
expected struct 'LoginRoute::Login::UserLoginResponse', found struct 'LoginService::Login:UserLoginResponse'
Please do not use the #[path = ...]
attribute for your typical organization; it should only be used in obscure cases. Each time you do mod something
, you are declaring a new module. Even if two modules point to the same file due to #[path = ...]
, they will be distinct.
So you have multiple UserLoginResponse
structs declared:
crate::LoginRoute::Login::UserLoginResponse
crate::LoginService::Login:UserLoginResponse
Login
in main.rs
.Since they're in distinct modules, the Rust compiler sees them as different types, which is not what you want.
Just use the idiomatic way of declaring modules. If you want to keep your existing folder structure without intermediate mod.rs
files, you can declare them all in main.rs
like so:
mod Models {
pub mod Login;
}
mod Routes {
pub mod LoginRoute;
}
mod Services {
pub mod LoginService;
}
And then access them elsewhere via crate::Models::Login
and whatnot.
See:
You've probably already run into warnings from the compiler trying to encourage a specific style: "module [...] should have a snake case name"
. Idiomatic file structure would typically look like this:
src/
models/
login.rs
mod.rs
routes/
login_route.rs
mod.rs
services/
login_service.rs
mod.rs
main.rs
Where main.rs
would have:
mod models;
mod routes;
mod services;
And src/models/mod.rs
(for example) would have:
pub mod login;