#yield #closures #detail #co #mcp-49 #yield-closure

yield-closures-impl

yield-closures库的实现细节

1 个不稳定发布

0.1.0 2021年11月23日

#11 in #co


yield-closures中使用

MIT 协议

11KB
182

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
~34K SLoC