In the following handle_input()
function, if Input
is the Text
or None
variant, an Output
returns.
Now, when the user presses Esc, Input
will be the Exit
variant. When that happens, the program/process will exit without running any command.
#[derive(Debug)]
pub enum Input {
Text(String),
None,
Exit,
}
fn handle_input(
input: Result<Input, std::io::Error>,
) -> Result<std::process::Output, std::io::Error> {
match input {
Ok(Input::Text(text)) => {
let output = std::process::Command::new("echo")
.arg(format!("{}", &text))
.output()?;
Ok(output)
}
Ok(Input::None) => {
let output = std::process::Command::new("echo")
.arg("Default text")
.output()?;
Ok(output)
}
Ok(Input::Exit) => {
// What should I return here?
}
Err(e) => Err(e),
}
}
fn get_input() -> Result<Input, std::io::Error> {
let input = "Argument text".to_owned();
// In the actual application, this may return other variants of `Input`.
Ok(Input::Text(input))
}
fn main() {
let input = get_input();
let output = handle_input(input).unwrap();
println!("{}", String::from_utf8_lossy(&output.stdout));
}
Rust Playground
What should I return in the Ok(Input::Exit)
of the match
arm? Right now, I get this error:
mismatched types
expected enum `Result<Output, std::io::Error>`
expected enum `Result<Output, std::io::Error>`
Because I'm not returning anything.
jofas
June 15, 2023, 3:32pm
2
If I understand what you want to achieve correctly, you can use std::process::exit
to exit your program. It returns !
(the never type), making it compatible with your other match arms.
2 Likes
If you don't want to exit the entire process immediately, either have a more complicated Ok
variant than std::process::Output
, or maybe a dedicated Err
variant (potentially still using io::Error
), and (either way) check for the clean exit request in main
(or wherever such processing actually occurs).
4 Likes
Slight non-sequitur but unless you have something you want to do specifically with the error variant, you can simplify handle_input
by using and_then
:
#[derive(Debug)]
pub enum Input {
Text(String),
None,
Exit,
}
fn handle_input(
input: Input,
) -> Result<std::process::Output, std::io::Error> {
match input {
Input::Text(text) => {
let output = std::process::Command::new("echo")
.arg(format!("{}", &text))
.output()?;
Ok(output)
}
Input::None => {
let output = std::process::Command::new("echo")
.arg("Default text")
.output()?;
Ok(output)
}
Input::Exit => {
// What should I return here?
todo!("fix this")
}
}
}
fn get_input() -> Result<Input, std::io::Error> {
let input = "Argument text".to_owned();
// In the actual application, this may return other variants of `Input`.
Ok(Input::Text(input))
}
fn main() {
let input = get_input();
let output = input.and_then(handle_input).unwrap();
println!("{}", String::from_utf8_lossy(&output.stdout));
}
1 Like
That's a good solution, thanks. But since the program will be exiting in handle_input()
, I won't be able the test that function, right?
jofas
June 16, 2023, 1:25pm
6
Right, if you were to test handle_input(Input::Exit)
, your test suite would exit. If that's a problem for you, please refer to quinedot's suggested solution of making either the Ok
or Err
variants of your return type more complicated by adding a variant that indicates that the user wishes to exit the program.
1 Like
Thanks for the suggestion. I think it'll work.
#[derive(Debug)]
pub enum Input {
Text(String),
None,
Exit,
}
#[derive(Debug)]
pub enum Output {
Success(std::process::Output),
Exit,
}
fn handle_input(input: Result<Input, std::io::Error>) -> Result<Output, std::io::Error> {
match input {
Ok(Input::Text(text)) => {
let output = std::process::Command::new("echo")
.arg(format!("{}", &text))
.output()?;
Ok(Output::Success(output))
}
Ok(Input::None) => {
let output = std::process::Command::new("echo")
.arg("Default text")
.output()?;
Ok(Output::Success(output))
}
Ok(Input::Exit) => {
Ok(Output::Exit)
}
Err(e) => Err(e),
}
}
fn get_input() -> Result<Input, std::io::Error> {
let input = "Argument text".to_owned();
Ok(Input::Exit)
}
fn main() {
let input = get_input();
let output = handle_input(input).unwrap();
println!("Output: {:?}", output);
}
Rust Playground
system
Closed
September 14, 2023, 1:51pm
8
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.