1

Im trying to create a hashmap that can be accessed and safely mutated across multiple routes using the actix-web. But for some reason , everything i access the GET url - i get the below response

App data is not configured, to configure use App::data()

my code is simple

async fn get_latest_timestamp(data: web::Data<Arc<Mutex<HashMap<String, String>>>>) -> String {
    
    // println!("data: {}", data);
    let wrapped_data = data.lock().unwrap();

    match wrapped_data.get("time_now") {
        Some(i) => String::from(i),
        None => String::from("None")
    }
}


#[actix_web::main]
async fn main() -> std::io::Result<()> {
    
    let mut hash = HashMap::new();
    hash.insert("time_now", Local::now().to_rfc2822());

    let data = Arc::new(Mutex::new(hash));

    // let data = web::Data::new(Mutex::new(hash));

    HttpServer::new( move || {
        App::new()
            .data(data.clone())
            .route("/", web::get().to(get_latest_timestamp))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

The solution here didnt help much as i tried wrapping the hashmap using both Arc as well as web::Data

Jayaram
  • 6,276
  • 12
  • 42
  • 78

1 Answers1

3

When going from App::data() to web::Data, the types must match exactly. Your hash is a HashMap<&str, String>, not a HashMap<String, String>.

You can fix this by using the right types on insert():

let mut hash = HashMap::new();
hash.insert(String::from("time_now"), Local::now().to_rfc2822());

Or a good trick is to annotate the type explicitly to ensure it is what you expect:

let mut hash: HashMap<String, String> = HashMap::new();
hash.insert("time_now", Local::now().to_rfc2822());
         // ^^^^^^^^^^ compiler now complains that this is the wrong type
kmdreko
  • 42,554
  • 6
  • 57
  • 106