Raw输入和输出

将代码拆分为多个文件

Rust与许多编程语言一样,main 方法通常只是提供应用的入口点,仅起到启动作用,而不会做其他事情。我们的目标是将代码放置在逻辑上合理的位置,以便在后续开发过程中更容易找到和维护。这种方法还有很多其他好处,我会在遇到时指出来。

现在,我们的代码有点难以理解。要真正理解它的作用,你必须深入研究它的全部内容。简而言之,它会回显用户按下的每个键,并在按下“q”时退出。让我们简化一下,一举两得:我们将为我们的编辑器引入一个名为Editor 的结构体,它将放在一个单独的文件editor.rs中。这将使代码更容易理解,也更符合语言习惯。

现在我们可以把注意力放在editor.rs上,editor.rs的内容可以是这样的:

use std::io;
use std::io::Read;
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};

pub struct  Editor{}

impl Editor {
    pub fn default() -> Self {
        Editor{}
    }

    pub fn run(&self) {
        enable_raw_mode().unwrap();
        for b in io::stdin().bytes() {
            match b {
                Ok(b) => {
                    let c = b as char;
                    if c.is_control() {
                        println!("Binary: {0:08b} ASCII: {0:#03} \r", b);
                    } else {
                        println!("Binary: {0:08b} ASCII: {0:#03} Character: {1:#?}\r", b, c);
                    }
                    if c == 'q' {
                        break;
                    }
                }
                Err(err) => println!("Error: {}", err),
            }
        }
        disable_raw_mode().unwrap();
    }
}

其实大体的逻辑就是把main.rs中的代码逻辑移动到了editor.rs中,然后我们修改main.rs的内容

use crate::editor::Editor;
mod editor;

fn main() {
    let editor = Editor::default();
    editor.run();
}

由于main.rs原来的代码逻辑迁移到了editor.rs中,所以现在新的main.rs代码很简洁

改进的错误处理

让我们通过解决关于错误处理的来总结一下惯用代码。我们的目标是:

作为其中的一部分,我们将错误处理逻辑与主循环分开,并打印出一条简单的再见消息。

use crossterm::event::{read, Event::Key, KeyCode::Char};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};

pub struct Editor {}

impl Editor {
    pub fn default() -> Self {
        Editor {}
    }
    pub fn run(&self) {
        if let Err(_err) = self.repl() {
            panic!("{_err:#?}");
        }
        print!("Goodbye.\r\n");
    }
    fn repl(&self) -> Result<(), std::io::Error> {
        enable_raw_mode()?;
        loop {
            if let Key(event) = read()? {
                println!("{event:?} \r");
                if let Char(c) = event.code {
                    if c == 'q' {
                        break;
                    }
                }
            }
        }
        disable_raw_mode()?;
        Ok(())
    }
}

按 Ctrl-Q 退出

目前,只要有人输入q,我们的文本编辑器就会退出,这不太理想。让我们来改变一下,让它只在你点击 时退出Ctrl-Q。

此外,随着代码越来越复杂,函数越来越多,我们需要一种更流畅的方法来关闭程序,而无需手动中断整个循环。

我们将通过调整Editor结构体来解决这个问题,使其包含一个名为 的布尔值should_quit。此修复还将消除 Clippy 的最终警告。