Assuming your goal is to convert license_path into a string, you can do this two ways, which differ in how they handle any non-UTF-8 sequences that may be in the path:
license_path.to_string_lossy().into_owned() replaces non-UTF-8 sequences with U+FFFD REPLACEMENT CHARACTER
license_path.display().to_string() escapes non-UTF-8 sequences using backslash escapes[1], but any backslash sequences that may already be in the path are not escaped again, making the result potentially ambiguous
I think; it's been a while since I last triggered this behavior ↩︎
You can't use format! for late-bound/dynamic string interpolation I'm afraid. format! only works with a string literal as its first argument, not variables or even constant string slices. You'll have to write your own interpolation logic (e.g. a simple license_string.replace("{author}", &author)), or use a more capable templating system, like handlebars.
Yes. You can't substitute format! here, as you already have observed. The arguments you pass to make_file are suboptimal though. license_string is already an owned string, so no need to call .to_owned() on it. And you can pass the license_path directly if you change the first argument type of make_file from &str to &Path or even better, make it generic like File::create, i.e. fn make_file(file: impl AsRef<Path>, content: String) -> std::io::Result<()>.
I wrote a simple template engine to solve the task. So you can replace ${name} with a value of name at runtime. For example:
let created = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis() as u64;
//let args = format!("{vec![Box::new(created}"))]; // created
let name:String = name.as_ref().to_string();
let name = simweb::interpolate(&name,&vec![Box::new(&created as &dyn Display)]);
let path:String=path.into();
let mut log_path = PathBuf::from(&path);
log_path.push(name.clone());
log_path.set_extension("log");
let file = File::create(&log_path).unwrap_or_else(|e| panic!("can't create log {log_path:?}/{e:?}"));