Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a variable initialized in main to a Rocket route handler?

I have a variable that gets initialized in main (line 9) and I want to access a reference to this variable inside of one of my route handlers.

#[get("/")]
fn index() -> String {
    return fetch_data::fetch(format!("posts"), &redis_conn).unwrap(); // How can I get redis_conn?
}

fn main() {
    let redis_conn = fetch_data::get_redis_connection(); // initialized here

    rocket::ignite().mount("/", routes![index]).launch();
}

In other languages, this problem would be solvable by using global variables.

like image 798
Max Avatar asked Mar 27 '19 18:03

Max


1 Answers

Please read the Rocket documentation, specifically the section on state.

Use State and Rocket::manage to have shared state:

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate rocket; // 0.4.2

use rocket::State;

struct RedisThing(i32);

#[get("/")]
fn index(redis: State<RedisThing>) -> String {
    redis.0.to_string()
}

fn main() {
    let redis = RedisThing(42);

    rocket::ignite()
        .manage(redis)
        .mount("/", routes![index])
        .launch();
}

If you want to mutate the value inside the State, you will need to wrap it in a Mutex or other type of thread-safe interior mutability.

See also:

  • Compiler says that data cannot be shared between threads safely even though the data is wrapped within a Mutex
  • Need holistic explanation about Rust's cell and reference counted types
  • Share i32 mutably between threads

this problem would be solvable by using global variables.

See also:

  • How do I create a global, mutable singleton?
like image 87
Shepmaster Avatar answered Oct 27 '22 17:10

Shepmaster