feat(calc): Inform user if qalc is not installed

This commit is contained in:
Michael Aaron Murphy 2021-10-06 17:06:51 +02:00 committed by Michael Murphy
parent 6cdf2987a9
commit bb4440e8a3

View file

@ -107,13 +107,23 @@ async fn qcalc(regex: &mut Regex, expression: &str, decimal_comma: bool) -> Opti
command.args(&["-set", "decimal comma on"]); command.args(&["-set", "decimal comma on"]);
} }
let mut child = command let spawn = command
.env("LANG", "C") .env("LANG", "C")
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::null()) .stderr(Stdio::null())
.spawn() .spawn();
.ok()?;
let mut child = match spawn {
Ok(child) => child,
Err(why) => {
return Some(if why.kind() == io::ErrorKind::NotFound {
String::from("qalc command is not installed")
} else {
format!("qalc command failed to spawn: {}", why)
})
}
};
if let Some(mut stdin) = child.stdin.take() { if let Some(mut stdin) = child.stdin.take() {
let _ = stdin let _ = stdin
@ -121,68 +131,73 @@ async fn qcalc(regex: &mut Regex, expression: &str, decimal_comma: bool) -> Opti
.await; .await;
} }
if let Some(stdout) = child.stdout.take() { let stdout = match child.stdout.take() {
let mut reader = smol::io::BufReader::new(stdout).lines().skip(2); Some(stdout) => stdout,
let mut output = String::new(); None => {
return Some(String::from(
"qalc lacks stdout pipe: did you get hit by a cosmic ray?",
));
}
};
fn has_issue(line: &str) -> bool { let mut reader = smol::io::BufReader::new(stdout).lines().skip(2);
line.starts_with("error") || line.starts_with("warning") let mut output = String::new();
fn has_issue(line: &str) -> bool {
line.starts_with("error") || line.starts_with("warning")
}
while let Some(Ok(line)) = reader.next().await {
let line = line.trim();
if line.is_empty() {
break;
} }
while let Some(Ok(line)) = reader.next().await { let normalized = regex.replace_all(line, "");
let line = line.trim(); let mut normalized = normalized.as_ref();
if line.is_empty() { if has_issue(normalized) {
break; return None;
} else {
if !output.is_empty() {
output.push(' ');
} }
let normalized = regex.replace_all(line, ""); if normalized.starts_with('(') {
let mut normalized = normalized.as_ref(); let mut level = 1;
for (byte_pos, character) in normalized[1..].char_indices() {
if character == '(' {
level += 1;
} else if character == ')' {
level -= 1;
if has_issue(normalized) { if level == 0 {
return None; normalized = normalized[byte_pos + 2..].trim_start();
} else { break;
if !output.is_empty() {
output.push(' ');
}
if normalized.starts_with('(') {
let mut level = 1;
for (byte_pos, character) in normalized[1..].char_indices() {
if character == '(' {
level += 1;
} else if character == ')' {
level -= 1;
if level == 0 {
normalized = normalized[byte_pos + 2..].trim_start();
break;
}
} }
} }
} }
}
let cut = if let Some(pos) = normalized.find('=') { let cut = if let Some(pos) = normalized.find('=') {
pos + 1 pos + 1
} else if let Some(pos) = normalized.find('≈') { } else if let Some(pos) = normalized.find('≈') {
pos + '≈'.len_utf8() pos + '≈'.len_utf8()
} else { } else {
return None; return None;
};
normalized = normalized[cut..].trim_start();
if normalized.starts_with('(') && normalized.ends_with(')') {
normalized = &normalized[1..normalized.len() - 1];
}
output.push_str(normalized);
}; };
}
return Some(output); normalized = normalized[cut..].trim_start();
if normalized.starts_with('(') && normalized.ends_with(')') {
normalized = &normalized[1..normalized.len() - 1];
}
output.push_str(normalized);
};
} }
None Some(output)
} }
pub async fn uses_decimal_comma() -> bool { pub async fn uses_decimal_comma() -> bool {