-
Notifications
You must be signed in to change notification settings - Fork 222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CompilerCommand::crate_provides #412
Conversation
Relates to capnproto#411 and capnproto#233 This api is quite awkward but I'm intending it as a stopgap until cargo supports non-linking DEP environment variables. But it allows people to use generated code in external crates without us needing to add an annotation to the external `.capnp` file. This is important because without the change to cargo it would be awkward to require users use a modified `json.capnp`.
The new api is like so fn main() {
capnpc::CompilerCommand::new()
.link_override(0xe6f94f52f7be8fe2, "external_crate")
.file("test.capnp")
.run()
.unwrap();
} I chose to call it After sleeping on it I think "link" is a better word here than "import". "use_override" or "extern_override" might also make sense to mirror the rust syntax. |
fix: forgot to change edition test crates fix: remove unused stuff I forgot
Hm... using the word "link" like this seems potentially confusing to me. This doesn't have anything to do with |
Agree "link" is wrong. What about |
Works for me. |
@@ -240,8 +257,15 @@ impl<'a> GeneratorContext<'a> { | |||
"{}_capnp", | |||
path_to_stem_string(importpath)?.replace('-', "_") | |||
); | |||
let parent_module_scope = if let Some(krate) = crates_provide.get(&import.get_id()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should happen if a file in ctx.request.get_requested_files()
has this ID too? Then the user is generating code for that file, and it seems to me that the crate-local version should win.
I think that, given an import ID X
, the precedence should be:
- If the user explicitly requests codegen a file with ID
X
, then that locally-generated version should be used, regardless of the contents ofcrates_provide_map
. - Otherwise, if
X
appears incrates_provide_map
, then that version of the name should be used. - Otherwise, if the referred-to file has a
$Rust.crate
annotation, then theText
crate name in that annotation should be used. - Otherwise, compile-time error (or graceful fallback).
I see that you removed the $Rust.crate
annotation from this pull request. I do think we should add that annotation. Up to you whether you want it to be in this pull request or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm tempted to say that if a user explicitly says a file should be provided by a crate and also explicitly asks to compile that file themselves we should fail with an error.
My guess is the main reason this would happen is that somebody was confused and thought they had to compile their imports. I can't think of a good reason you'd ever do this.
I agree $Rust.crate should be overridden by the build script option. I removed it because I was thinking it'd only be useful once we had the cargo feature but on second thought I think it's useful right away. I'll add it back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm tempted to say that if a user explicitly says a file should be provided by a crate and also explicitly asks to compile that file themselves we should fail with an error.
Yeah that makes sense. I was forgetting that they need to explicitly opt into each individual file in crate_provides()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of fallbacks I don't think it's that important. c++.capnp doesn't have any annotations with non built-in types, so I think it's unlikely users will have such annotations in their code and not want to parse the annotations in Rust.
If it's a field instead of an annotation I can't think of a use case where a fallback would be useful.
Another possible API would be to fail with a helpful error message that suggests adding an explicit exclude_annotations(file_id) call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was imagining a schema created for C++ project, where it has a bunch of $Json annotations sprinkled in. A Rust project might not care about JSON and might not want to add a dependency on the capnp_json
crate. So I think some way to ignore the annotations is needed. However, since there's probably more discussion to be had about it, and since nobody is actually complaining about it yet, I think it does not belong in the current PR.
|
[capnpc] add `crate_provides()` to specify that an imported schema is provided by another crate
Relates to #411 and #233
I'm intending this as a stopgap until cargo supports non-linking DEP environment variables. It allows people to use generated code in external crates without us needing to add an annotation to the external
.capnp
file. This is important because without the change to cargo it would be awkward to require users use a modifiedjson.capnp
.Unfortunately capnproto doesn't support annotations on import statements.