[Solved] Pass a string literal in Rust


#1

I am using a sofa crate for accessing couchdb database.
https://docs.rs/sofa/0.6.0/sofa/

        let dbw = client.db("my_database_name");

This works as the clent.db function expects a &'static str input.

Now i want to pass this value from a json configuration file. so i read from json file and want to pass cfg.database variable to the function.

    let json = include_str!("../config.json");
    let cfg = serde_json::from_str::<Config>(&json).unwrap();
    println!("{}", cfg.database);

If i pass this value directly…

        let dbw = client.db(&cfg.database);

compiler suggest this error: borrowed value does not live long enough rustc(E0597) :scream:

how should i pass this as a constant string literal to his client.db() function?
Please help :pray:


#2

I’d suggest asking the sofa devs to relax that to any &str, because at a glance it doesn’t seem like they actually need that lifetime.


#3

Simply put, a &'static str has to be known at compile time.

I’m not sure why that library is requiring that, because it will prevent users from having any runtime-generated strings be used as the database name. As it’s written, you would need to hardcode the database name in Rust, or use include_str! on a file that contained only the database name. The way it’s written on the sofa side is very limiting, because it means you can’t use a configuration file or environment variable to determine database name.


#4

Thanks @cuviper and @natemara for your response. I was struggling with the the compiler for a few hours wondering why i was not able to fix it. Now i understand this better. will ask sofa crate devs to relax the lifetime here.


#5

Take a look at the source; if it really doesn’t seem that it’s necessary then you can probably use some unsafe magic to get around it until they change the requirements.


#6

You can also create &'static str by leaking a String on the heap, Box::leak(s.into_boxed_str()), but of course that’s not desirable.


#7

I was not aware of that, thanks!


#8

@cuviper i was trying your suggestion

    const database : &'static str = Box::leak(cfg.database.into_boxed_str());

Compiler suggest this… am i doing anything wrong?

can’t capture dynamic environment in a fn item
help: use the || { ... } closure form instead rustc(E0434)
let cfg = serde_json::from_str::(&json).unwrap();


#9

Don’t use const (you’re not creating a const), just a normal let binding.

Instead of leaking the string, as a workaround until sofa is changed, I’d probably just transmute the lifetime to be &'static just for the call to client.db(...).


#10

Thank you it worked now.
Thanks @vitalyd @cuviper @natemara @OptimisticPeach you guys are super helpful!! :bowing_man:


#11

Ah, that makes more sense than possibly introducing more bugs than an unsafe block