Home > Mobile >  How can I try reading data from a file or else return empty string?
How can I try reading data from a file or else return empty string?

Time:09-27

I would like to read a specific line of a file, if the:

  • file does not exist
  • file cannot be open
  • the number of lines is less that the one that I want

just return an empty string.

Consider the following examples:

let wifi = "".to_string();
if let Ok(wifi_file) = fs::read_to_string("/proc/net/wireless") {
    if let Some(wifi_level) = wifi_file.lines().nth(2) {
        let wifi = format!("{:.0} dBa ", wifi_level
            .split_whitespace()
            .collect::<Vec<&str>>()[3]
            .parse::<f32>()
            .unwrap()
        );
    }
}
// wifi is out of scope
let wifi = match fs::read_to_string("/proc/net/wireless") {
    Ok(s) => format!("{:.0} dBA", s.lines()
        .nth(2)
        .expect("Unable to open")
        .split_whitespace()
        .collect::<Vec<&str>>()[3]
        .parse::<f32>()
        .unwrap()),
    Err(_) => "".to_string(),
};
// thread 'main' panicked at 'Unable to open', ...

Am I missing something obvious about match?

CodePudding user response:

In your first code, you are declaring wifi variable again instead of using the already declared variable.

Working code:

let mut wifi = "".to_string();
if let Ok(wifi_file) = fs::read_to_string("/proc/net/wireless") {
    if let Some(wifi_level) = wifi_file.lines().nth(2) {
        wifi = format!("{:.0} dBa ", wifi_level
            .split_whitespace()
            .collect::<Vec<&str>>()[3]
            .parse::<f32>()
            .unwrap()
        );
    }
}

Second code is working without any changes.

CodePudding user response:

You already have an answer, but this code can be simplified if you encapsulate it in a function returning an Option and use ? for none-propagation:

fn get_wifi(path: &str, n: usize) -> Option<String> {
    let file = std::fs::read_to_string(path).ok()?;
    let level = file.lines().nth(n)?;
    let value = level.split_whitespace().nth(3)?.parse::<f32>().ok()?;
    
    Some(format!("{:.0} dBa ", value))
}

You can then call it like this:

let wifi = get_wifi("/proc/net/wireless", 2).unwrap_or_default();
  • Related