Linked Questions

Popular Questions

This is just an example of an (still incomplete) real-world project written in Rust using a clean architecture: https://github.com/frederikhors/rust-clean-architecture-with-db-transactions.

Goals

My intent is to have an app build in 4 layers:

  • entities:

    • some call this layer "domain", not important for now, just the minimum
  • services:

    • some call this layer "use cases", this is where business logic lives (just CRUD methods for now)
  • repositories:

    • some call this layer "adapters", this is where concrete implementation of DB/cache/mail drivers lives
  • ports:

    • some call this layer "controllers or presenters", still not present and not important for now, I'm using main.rs for this

Reproduction

https://codesandbox.io/p/github/frederikhors/rust-clean-architecture-with-db-transactions/main

The issue

If you open the main.rs file you can see the issue:

// This obviously works if alone:
// let db_repo = Arc::new(repositories::in_memory::Repo::new());

// This obviously works if alone:
// let pg_pool = Arc::new(sqlx::PgPool::connect("postgres://postgres:postgres@localhost:5432/postgres").await.unwrap());
// let db_repo = Arc::new(repositories::postgres::Repo::new(pg_pool));

// This doesn't work instead:
let db_repo = if use_postgres {
    let pg_pool = Arc::new(sqlx::PgPool::connect("postgres://postgres:postgres@localhost:5432/postgres").await.unwrap());

    Arc::new(repositories::postgres::Repo::new(pg_pool))
} else {
    Arc::new(repositories::in_memory::Repo::new())
};

My intent here is to change repository in use based on a variable, but Rust doesn't like it, this is the error:

Expand the error
error[E0308]: `if` and `else` have incompatible types
--> src\main.rs:37:9
|
28 |       let db_repo = if use_postgres {
|  ___________________-
29 | |         let pg_pool = Arc::new(
30 | |             sqlx::PgPool::connect("postgres://postgres:postgres@localhost:5432/postgres")
31 | |                 .await
...  |
35 | |         Arc::new(repositories::postgres::Repo::new(pg_pool))
| |         ---------------------------------------------------- expected because of this
36 | |     } else {
37 | |         Arc::new(repositories::in_memory::Repo::new())
| |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `repositories::postgres::Repo`, found struct `in_memory::Repo`
38 | |     };
| |_____- `if` and `else` have incompatible types
|
= note: struct `in_memory::Repo` and struct `repositories::postgres::Repo` have similar names, but are actually distinct types
note: struct `in_memory::Repo` is defined in module `crate::repositories::in_memory` of the current crate
--> src\repositories\in_memory\mod.rs:6:1
|
6  | pub struct Repo {
| ^^^^^^^^^^^^^^^
note: struct `repositories::postgres::Repo` is defined in module `crate::repositories::postgres` of the current crate
--> src\repositories\postgres\mod.rs:6:1
|
6  | pub struct Repo {
| ^^^^^^^^^^^^^^^

How can I fix this?

Related Questions