深度嵌套枚举的更清晰的匹配臂

Kur*_*aum 2 rust

我有以下带有匹配表达式的函数:

fn handle_event<'e>(&mut self, event: Event<'e>) -> Event<'e> {
    match (&event, &self.current_lang) {
        (Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(lang))), _) => {
            self.start_fenced_code_block(&lang)
        }
        (Event::End(Tag::CodeBlock(CodeBlockKind::Fenced(_))), _) => {
            self.end_fenced_code_block()
        }
        (Event::Text(text), Some(lang)) => self.code_html(&text, &lang),
        _ => event,
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,由于深层嵌套的枚举,前两个手臂感觉像是失控了。所以我做了一些宏:

macro_rules! fenced_code_block_start {
    ($lang:pat_param) => {
        Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced($lang)))
    };
}
macro_rules! fenced_code_block_end {
    () => {
        Event::End(Tag::CodeBlock(CodeBlockKind::Fenced(_)))
    };
}
Run Code Online (Sandbox Code Playgroud)

现在我有了,恕我直言,更清洁的:

match (&event, &self.current_lang) {
    (fenced_code_block_start!(lang), _) => self.start_fenced_code_block(&lang),
    (fenced_code_block_end!(), _) => self.end_fenced_code_block(),
    (Event::Text(text), Some(lang)) => self.code_html(&text, &lang),
    _ => event,
}
Run Code Online (Sandbox Code Playgroud)

但是,我想知道是否有更好的方法来做到这一点。陷入宏总是让我停顿。我可以在这里使用 Rust 的其他一些功能,而不是那么沉重的锤子吗?

kmd*_*eko 6

如果不丢失清晰度,您可以直接导入并使用枚举变体:

fn handle_event<'e>(&mut self, event: Event<'e>) -> Event<'e> {
    use Event::*;
    use Tag::*;
    use CodeBlockKind::*;
    
    match (&event, &self.current_lang) {
        (Start(CodeBlock(Fenced(lang))), _) => self.start_fenced_code_block(&lang),
        (End(CodeBlock(Fenced(_))), _) => self.end_fenced_code_block(),
        (Text(text), Some(lang)) => self.code_html(&text, &lang),
        _ => event,
    }
}
Run Code Online (Sandbox Code Playgroud)