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();