capnproto / capnproto-rust

Cap'n Proto for Rust
MIT License
1.99k stars 220 forks source link

introduce canonical way to import stream.capnp and other core schemas #430

Open dwrensha opened 11 months ago

dwrensha commented 11 months ago

See https://github.com/capnproto/capnproto-rust/issues/230#issuecomment-1690113298.

The capnp-rpc does not yet natively support streaming methods. Methods that use the streaming keyword are supposed to fall back to the StreamResult struct, but there is currently no canonical way to refer to that struct in Rust code. To get this to work today, a downstream project will need to generate rust code for stream.capnp. Probably it will go into that project's crate/namespace, which feels wrong.

Perhaps we should include generated code for stream.capnp in the base capnp crate, and auto-populate crate_provides_map to refer to that generated code.

tamird commented 11 months ago

Relatedly: is there a tracking issue for native steam support?

dwrensha commented 11 months ago

I don't think so. Please feel free to open one.

sanderpick commented 10 months ago

If I include https://github.com/capnproto/capnproto/blob/master/c%2B%2B/src/capnp/stream.capnp in my project and ask the compiler to generate code for it, I get an error about the ID already existing:

/usr/include/capnp/stream.capnp:1:1: error: Duplicate ID @0x86c366a91393f3f8.
  schema/stream.capnp:1:1: error: ID @0x86c366a91393f3f8 originally used here.
  /usr/include/capnp/stream.capnp:30:8-20: error: Duplicate ID @0x995f9a3377c0b16e.
  schema/stream.capnp:30:8-20: error: ID @0x995f9a3377c0b16e originally used here.

ie, stream.capnp already exists on my system. If I instead reference the file directly in the build script like...

fn main() {
    capnpc::CompilerCommand::new()
        .src_prefix("src")
        .file("/usr/include/capnp/stream.capnp")
        .file("schema/definitions.capnp")
        .file("schema/provider.capnp")
        .output_path("src")
        .default_parent_module(vec!["schema".to_string()])
        .run()
        .expect("protocol compiler command failed");
}

The compiler creates a file structure src/usr/include/capnp/stream_capnp.rs, which means that type referenced by my other schemas (eg, crate::schema::stream_capnp::stream_result::Owned) are not visible.

I can just move src/usr/include/capnp/stream_capnp.rs to src/schema and remove .file("/usr/include/capnp/stream.capnp") from the build script, but not ideal.

I'm mentioning this because above you say, "Probably it will go into that project's crate/namespace", which doesn't work "out of the box".

Perhaps we should include generated code for stream.capnp in the base capnp crate, and auto-populate crate_provides_map to refer to that generated code.

This would be good!

JonasVautherin commented 4 months ago

Perhaps we should include generated code for stream.capnp in the base capnp crate, and auto-populate crate_provides_map to refer to that generated code.

@dwrensha: Is that a difficult thing to do? I would be willing to have a look, but I would need some directions to get started :innocent:.