Search code examples
rustrust-rocket

An opened image as a global variable?


I'd like to write a server that resizes a huge image. Since loading it on every request would take a lot of time, I decided to pre-load it. Unfortunately I got the following error:

   Compiling hello_world v0.0.0 (/tmp/Rocket/examples/hello_world)                                                                                                                                                                                                                                                                                                         
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants                                                                                                                                                                                                                                                                         
 --> examples/hello_world/src/main.rs:9:35                                                                                                                                                                                                                                                                                                                                 
  |                                                                                                                                                                                                                                                                                                                                                                        
9 | static img: image::DynamicImage = image::open("/home/d33tah/tmp/combined.png").unwrap();                                                                                                                                                                                                                                                                               
  |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                                                                                                                                                                         

error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants                                                                                                                                                                                                                                                                         
 --> examples/hello_world/src/main.rs:9:35                                                                                                                                                                                                                                                                                                                                 
  |                                                                                                                                                                                                                                                                                                                                                                        
9 | static img: image::DynamicImage = image::open("/home/d33tah/tmp/combined.png").unwrap();                                                                                                                                                                                                                                                                               
  |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                                                                                                                                                                

error: aborting due to 2 previous errors                                                                                                                                                                                                                                                                                                                                   

For more information about this error, try `rustc --explain E0015`.                                                                                                                                                                                                                                                                                                        
error: Could not compile `hello_world`.                                                                                                                                                                                                                                                                                                                                    

To learn more, run the command again with --verbose.

Here's the code:

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

#[cfg(test)] mod tests;

extern crate image;

static img: image::DynamicImage = image::open("/home/d33tah/tmp/combined.png").unwrap();

#[get("/")]
fn hello() -> Vec<u8> {
    "".into()
}

fn main() {
    rocket::ignite().mount("/", routes![hello]).launch();
}

To compile it, you'll need rocket installed based on its latest Github checkout (currently: 831d8dfbe30dd69f0367a75361e027127b2100e1) and image crate.

Is it possible to create such a global variable? If not, do I have any other options?

EDIT: this was flagged as a duplicate of this question, but as Boiethios showed, this specific case is better solved by Rocket's API.


Solution

  • If you want to share something in Rocket, you will have to use a managed state:

    1. Say to Rocket you want to manage the resource:

      let image = image::open("/home/d33tah/tmp/combined.png").unwrap();
      rocket::ignite().manage(image);
      
    2. Retrieve it in the routes where you need it:

      #[get("/foo")]
      fn foo(image: State<DynamicImage>) {
          // Can use `image`.
      }