I'm not sure where these two functions belong to

I created a Screen struct with methods to manipulate stdout. For example, to show the cursor or display prompts (in the terminal).

I created the handle_input() and handle_input_result() to make main() smaller and prevent code duplication. These methods control the flow of the code based on the value of prompt and variants of Input.

Note: this is mock code that shows the structure of the actual application.

use std::io::Write;

#[derive(Debug)]
pub enum Input {
    Text(String),
    None,
    Exit,
}

struct Screen {
    stdout: Vec<u8>,
}

impl Write for Screen {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        self.stdout.write(buf)
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.stdout.flush()
    }
}

impl Screen {
    fn new(stdout: Vec<u8>) -> Self {
        Screen { stdout }
    }

    fn show_cursor(&mut self) {
        write!(self.stdout, "Show cursor!").unwrap();
    }

    fn show_prompt(&mut self, message: &str) {
        write!(self.stdout, "{}\r\n", message).unwrap();
    }

    fn handle_input(&mut self, prompt: Option<String>) -> Result<Input, std::io::Error> {
        match prompt {
            Some(_) => {
                self.show_prompt(&prompt.unwrap());
                let input = get_input()?;

                Ok(input)
            }
            None => {
                self.show_cursor();
                Ok(Input::None)
            }
        }
    }

    fn handle_input_result(&mut self, input: Input) {
        match input {
            Input::Text(text) => {
                self.show_cursor();
                println!("{}", &text);
            }
            Input::None => {
                self.show_cursor();
                println!("None");
            }
            Input::Exit => {
                println!("Exit");
            }
        }
    }
}

fn get_input() -> Result<Input, std::io::Error> {
    let input = "This is some text".to_owned();

    // In the actual application, this may return other variants of `Input`.
    Ok(Input::Text(input))
}

fn main() {
    let mut screen = Screen::new(Vec::new());
    
    // In the actual application, `prompt` belongs to a struct called `Keymap`.
    let prompt = Some("This is a prompt".to_string());
    let input = screen.handle_input(prompt);

    screen.handle_input_result(input.unwrap());
}

Design-wise, do handle_input() and handle_input_result() belong to Screen? If not, what should I do with them?

Rust Playground

They do seem to be at a somewhat different level of abstraction. If you care to separate them, you could

  • Have a struct that contains Screen and put them there
  • Have an trait for "prompt logic" and put them there
1 Like

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.