Unterminated character literal

I was working on this code to rename a large chunk of files to a similar name, like png_1 ( mainly for practice not efficiency) and I got the following error:

error: unterminated character literal
  --> src\main.rs:14:51
   |
14 |         let mut var 'static std::path::Display<'_>' = path.unwrap().path().display();
   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: could not compile `RenameFiles`.

Here is the Code:

use std::{env, fs};

   fn main() {
   let dir = fs::read_dir("C:\\Users\\feded\\Desktop\\test_rust").unwrap();
   let base_name_text = String::from("Enter a base name for the files to edit");
   let extension_text = String::from("Enter the extention for the files who's name needs to be edited");
   let base_name = input(base_name_text).to_owned();
   let extension = input(extension_text);
   let mut value = 1; 
   println!("Old Path names");
   for path in fs::read_dir("C:\\Users\\feded\\Desktop\\test_rust").expect("couldn't find specific path") {
       
       let mut strvalue = &value.to_string().to_owned();
       let mut var 'static std::path::Display<'_>' = path.unwrap().path().display();

       //let mut path: 'static std::path::Display<'_>' = &var;
       if var.to_string().contains("C:\\Users\\feded\\Desktop\\test_rust"){
           var.to_string().pop();
       }
       if var.to_string().contains(".jpg"){
           
           println!("{}", var.to_string());
           fs::rename(var.to_string(), format!("{}_{}.png", base_name.to_string(), strvalue));
       }else if var.to_string().contains(".png"){
           println!("{}", var.to_string());
           let new_string = base_name + "_" + strvalue + ".png";
           fs::rename(var.to_string(), new_string);
       }else {
           continue;
       }

       value += 1;
       
   }
   }


   fn input(text: String) -> String {
   use std::io::{stdin,stdout,Write};
   let mut input = String::new();
   println!("{}", text);
   let _=stdout().flush();
   stdin().read_line(&mut input).expect("Did not enter a correct string");
   if let Some('\n')=input.chars().next_back() {
       input.pop();
   }
   if let Some('\r')=input.chars().next_back() {
       input.pop();
   }

   return input;
   }

The error message shows exactly where the error starts. Change

let mut var 'static std::path::Display<'_>' =

to

let mut var 'static std::path::Display<'_> =

The 'something syntax is lifetime annotation, not a string. Sometimes code editors helpfully "close" such "strings" and inject extra ' where they shouldn't.


Rust idiomatic style is to avoid writing types where type inference knows them, so you can write it much nicer:

let mut var = path.unwrap().display();

Also path's .display() is a thin temporary wrapper, not the path. It's usually not kept around, but only called on-demand when you need to print the path. Keep the path in variable instead.

After removal of nonrelevant stuff, providing a minimal nonworking example:

const DIR: &str = "C:\\Users\\feded\\Desktop\\test_rust";

fn main() {
    for path in std::fs::read_dir(DIR).unwrap() {
        let mut var 'static std::path::Display<'_>' = path.unwrap().path().display(); 
        let _s = var.to_string();
    }
}

Correct syntax is

let mut identifier: Type = value;

That 'static is a lifetime, which only occur after & and as type arguments (wrapped in angle brackets). Let's fix it according to the compiler:

let var: std::path::Display<'_> = path.unwrap().path().display(); 
let _s = var.to_string();

Now introduce a temporary to satisfy the borrow checker:

let temp = path.unwrap().path();
let var: std::path::Display<'_> = temp.display(); 
let _s = var.to_string();

Now in compressed form and with correct meaning:

fn main() {
    for entry in std::fs::read_dir(DIR).unwrap() {
        let path = entry.unwrap().path();
        let _s = path.display().to_string();
    }
}

Thanks for the speedy response, I decided to work on a more condensed and readable version of my code by taking your advice, I ended up with the following:

use std::{env, fs};
const DIR: &str = "C:\\Users\\feded\\Desktop\\test";

fn main(){
    
    let mut tick = 1;
    let root = "pic";
    for entry in std::fs::read_dir(DIR).unwrap() {
        let path = entry.unwrap().path(); 
        let s = path.display().to_string();
        let file_names: &str = &s[28..s.len() - 3];
        let file_paths: &str = &s[0..28]; 
        let extention: &str = &s[s.len()-3..s.len()];
        
        fs::rename(&s, format!("{}{}_{}.{}", file_paths, root, tick.to_string(), extention));
        
        tick += 1;
    }
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.