#yield #closures #co #mcp-49

yield-closures

MCP-49 的实现

1 个不稳定版本

0.1.0 2021 年 11 月 23 日

#4 in #co

MIT 许可证

8KB
144

yield-closures

MCP-49 的实现。

#[test]
fn decode_escape_string() {
    let escaped_text = "Hello,\x20world!\\n";
    let text: String = escaped_text
        .chars()
        .filter_map(co!(|c| {
            loop {
                if c != '\\' {
                    // Not escaped
                    yield Some(c);
                    continue;
                }

                // Go past the \
                yield None;

                // Unescaped-char
                match c {
                    // Hexadecimal
                    'x' => {
                        yield None; // Go past the x
                        let most = c.to_digit(16);
                        yield None; // Go past the first digit
                        let least = c.to_digit(16);
                        // Yield the decoded char if valid
                        yield (|| char::from_u32(most? << 4 | least?))()
                    }
                    // Simple escapes
                    'n' => yield Some('\n'),
                    'r' => yield Some('\r'),
                    't' => yield Some('\t'),
                    '0' => yield Some('\0'),
                    '\\' => yield Some('\\'),
                    // Unnecessary escape
                    _ => yield Some(c),
                }
            }
        }))
        .collect();
    assert_eq!(text, "Hello, world!\n");
}

有关提案的详细信息,请参阅 https://lang-team.rust-lang.org/design_notes/general_coroutines.html

此实现与提案之间的差异总结如下

  • 此软件包提供了一个宏实现。它与稳定版本的 Rust 一起工作。
  • 不提供 FnPin。使用此软件包制作的 yield 闭包内部使用 Box::pin 并因此使用 FnMut
  • 在 yield 闭包中,不能使用 return 表达式。
  • yield 闭包的主体必须是爆炸性的,即不能返回,并且通过 ! 类型进行类型化。因此,它与 MCP-49 文档中讨论的两个 yield 闭包设计都兼容:默认中毒或不中毒。

依赖关系

~1.5MB
~35K SLoC