How to avoid copying data from calling &Vec<T>.to_vec() on every HTTP response in Rust

I am trying to cache an HTTP response of raw JSON data. The following seems to work but having to call &Vec<T>.to_vec() on every response seems inefficient if the data is copied each time. Is there a way to avoid this? Perhaps maybe using a &[u8] instead of a Vec<u8>?

use std::collections::HashMap;
use std::fs;
  
use rocket::response::content::RawJson;
use rocket::State;
  
#[rocket::get("/")]
fn coming_up(cache: &State<HashMap<&str, Vec<u8>>>) -> RawJson<Vec<u8>> {
  RawJson(cache.get("coming_up").unwrap().to_vec())
}
  
#[rocket::launch]
fn run() -> _ {
  let mut cache = HashMap::new();
  let fixtures = fs::read("sample_fixtures.json").unwrap();
  cache.insert("coming_up", fixtures);
  
  rocket::build()
    .manage(cache)
    .mount("/api/v2/fixtures", rocket::routes![coming_up])
}

The RawJson type requires something that implements the Responder trait, and looking over the list of things that implement the trait, I see Arc<[u8]>. This type can do what you want. You create it by doing Arc::from(fixtures.as_slice()), and the type is nice because cloning it doesn't actually copy the data — it just increments a counter.

3 Likes

Thank you @alice!