Hello,
I have a practical question which also happens to be conceptual and for whych I am having trouble finding a solution.
It will be easier to explain with a simple piece of code which will not compile:
use testcontainers::clients::Cli;
use testcontainers::images::postgres::Postgres;
use testcontainers::RunnableImage;
pub type DockerClient = Cli;
pub struct Database<'a> {
container: testcontainers::Container<'a, Postgres>,
docker_client: DockerClient,
}
impl<'a> Database<'a> {
pub fn run() -> Self {
let postgres_image = RunnableImage::from(Postgres::default())
.with_tag("13")
.with_env_var(("POSTGRES_DB", "test_database"))
.with_env_var(("POSTGRES_USER", "postgres"))
.with_env_var(("POSTGRES_PASSWORD", "postgres"))
.with_mapped_port((5433, 5432));
let docker_client = DockerClient::default();
let container = docker_client.run(postgres_image);
Self {
container,
docker_client,
}
}
}
fn main() {
println!("hello");
}
The only dependency to run this code is
testcontainers = "0.13.0"
Why doesn't this compile
Based on my understanding, this does not compile because the method run() on the DockerClient creates a container which takes a reference to the docker_client instance on which the run method is called.
So we have a cycle here, stating that the DockerClient which creates a container must live at least the same time or longer than the created container, because if it dies first then the created container will have a dangling reference.
Ok, so far so good.
The problem
But in my code, I am saving both the DockerClient and the created container on the Database struct, effectively coupling the life of these two pieces of data together. When Database goes out of scope, both (the client and the created container) will be dropped. So, in my opinion, the created container will not have a dangling reference, because the Database struct instance owns both the client and the container and will drop these together.
But how do I express this to the compiler so that it will understand me? Because the way things are now I got an compilation error stating that I am trying to return a data owned by the function and I am, but at the same time I am offering (or at least so is my goal) guarantees that this owned data is being moved somewhere where the owning data will haver access to it.
Thanks,
Marlon