feat(calc): Inform user if qalc is not installed
This commit is contained in:
parent
6cdf2987a9
commit
bb4440e8a3
1 changed files with 65 additions and 50 deletions
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue