PR #193 merges in an Opts::standalone flag intended to assist in generating code into standalone source files, with the ultimate intention being to precompile those files into external crates referenced by a user's component project.
One of the motivators for doing so is to give a close-as-possible experience to cargo today for consuming dependencies from a registry, but instead of referencing Rust crates, one references components and the bindings are generated into external crates. This leads to a more natural way of consuming component dependencies for Rust developers.
For example:
use backend::Backend;
struct Component;
impl Backend for Component {
fn fetch(url: String) -> Vec<u8> {
if let Some(data) = cache::get(&url) {
return data;
}
let data = origin::fetch(&url);
cache::put(&url, &data);
data
}
}
backend::export!(Component);
With the above, the backend, cache, and origin crates are all from generated bindings based on references in Cargo.toml.
See this gist for the currently generated code for the above example in "standalone" mode.
The generated backend::export! macro is used to declare that the Component type exports the backend interface. This is also needed to allow for the possibility of having a singular component type which exports multiple component interfaces.
However, we don't want to have two different "modes" for code generation for Rust. To make the above example work for the existing proc-macros and for generating code into standalone crates, we would need to remove all dependencies on super from the generated code.
This presents a problem for supporting resources however:
HandleType is implemented for an expected type name in super.
LocalHandle is implemented for an expected type name in super.
canonical_abi_drop_<resource> implementation and the generated trait's drop_<resource> method are implemented for an expected type name in super.
- Calling static or resource methods from the exported functions is implemented for an expected type name in
super.
The problem also presents itself for any types that contain a handle to a resource, as the type's definition needs to know the user's implementation type for the resource, which is not present in the bindings crate (it's the same reason the generated export! macro exists in the above example to provide the backend crate with the name of the type implementing the Backend trait to call).
If and when we redesign resource code generation to accommodate for standalone bindings crates, we should remove the "standalone" option and have a single output for Rust bindings.
PR #193 merges in an
Opts::standaloneflag intended to assist in generating code into standalone source files, with the ultimate intention being to precompile those files into external crates referenced by a user's component project.One of the motivators for doing so is to give a close-as-possible experience to
cargotoday for consuming dependencies from a registry, but instead of referencing Rust crates, one references components and the bindings are generated into external crates. This leads to a more natural way of consuming component dependencies for Rust developers.For example:
With the above, the
backend,cache, andorigincrates are all from generated bindings based on references inCargo.toml.See this gist for the currently generated code for the above example in "standalone" mode.
The generated
backend::export!macro is used to declare that theComponenttype exports thebackendinterface. This is also needed to allow for the possibility of having a singular component type which exports multiple component interfaces.However, we don't want to have two different "modes" for code generation for Rust. To make the above example work for the existing proc-macros and for generating code into standalone crates, we would need to remove all dependencies on
superfrom the generated code.This presents a problem for supporting resources however:
HandleTypeis implemented for an expected type name insuper.LocalHandleis implemented for an expected type name insuper.canonical_abi_drop_<resource>implementation and the generated trait'sdrop_<resource>method are implemented for an expected type name insuper.super.The problem also presents itself for any types that contain a handle to a resource, as the type's definition needs to know the user's implementation type for the resource, which is not present in the bindings crate (it's the same reason the generated
export!macro exists in the above example to provide thebackendcrate with the name of the type implementing theBackendtrait to call).If and when we redesign resource code generation to accommodate for standalone bindings crates, we should remove the "standalone" option and have a single output for Rust bindings.