2 unstable releases
0.2.0 | Apr 12, 2023 |
---|---|
0.1.0 | Feb 28, 2023 |
#13 in #smithy
255 downloads per month
Used in wasmcloud-provider-httpse…
380KB
8K
SLoC
smithy-bindgen
This crate provides macros for generating rust bindings from smithy interfaces.
For most uses of smithy interfaces used to generate rust sources,
this can eliminate the need for build.rs
and codegen.toml
files.
codegen.toml
is still needed to generate bindings for other languages.
Feedback welcome!
This is a first pass at code generation macro, inspired by
wit-bindgen
. If you have usedcodegen.toml
, please let us know if this works as a replacement. (one known omission: theparams
setting from codegen.toml is not yet available in this macro) Other variations may be introduced in the future: one for actor-specific interfaces, provider-specific interfaces, etc.
Quick-start
We recommend that the smithy_bindgen!
macro is used inside a mod
declaration,
or by itself in a separate rust source file, to avoid symbol conflicts with your code.
If you're using a wasmcloud first-party interface, you can specify its path name (relative to the wasmcloud/interfaces repo), followed by its namespace:
// [dependencies]
// smithy-bindgen = "0.1"
mod httpserver {
smithy_bindgen::smithy_bindgen!("httpserver/httpserver.smithy","org.wasmcloud.interfaces.httpserver");
}
use httpserver::{HttpRequest,HttpResponse};
If you have a smithy interface defined locally, you can load it
mod amazing_foo {
smithy_bindgen::smithy_bindgen!(
{ path: "./amazing_foo.smithy" }, "org.example.interfaces.foo"
);
}
use amazing_foo::{Bazinga, Wowza};
Additional syntax forms are listed below.
Note This doesn't replace all the functionality of wasmCloud's interface crates. A few of the wasmCloud interface crates have hand-generated helper functions that are not part of the smithy files. For example,
wasmcloud-interface-httpserver
containsimpl Default
and a few constructors forHttpResponse
. Those are not generated bysmithy_bindgen!
. We are planning to move those extra helper functions into a future wasmcloud sdk.
Syntax
The first parameter of the smithy_bindgen!
macro can take one of three forms.
The second parameter is the namespace used for code generation.
-
one wasmcloud first-party interface
The single-file parameter is a path relative to the wasmcloud interfaces git repo
wasmcloud/interfaces
smithy_bindgen!("httpserver/httpserver.smithy", "org.wasmcloud.interfaces.httpserver");
The above is shorthand for the following:
smithy_bindgen!({ url: "https://cdn.jsdelivr.net/gh/wasmcloud/interfaces", files: ["httpserver/httpserver.smithy"] }, "org.wasmcloud.interfaces.httpserver" );
-
one Model Source
smithy-bindgen!({ path: "../interfaces/foo.smithy", }, "org.example.interfaces.foo" );
-
array of Model Sources
smithy-bindgen!([ { path: "../interfaces/foo.smithy" }, { url: "keyvalue/keyvalue.smithy" }, ], "org.example.interfaces.foo" );
Model Source Specification
A model source contains a url
, for http(s) downloads, or a path
, for local fs access, that serves as a base, plus files
, an optional list of file paths that are appended to the base to build complete url download paths and local file paths.
When joining the sub-paths from the files
array, '/' is inserted or removed as needed, so that there is exactly one between the base and the sub-path.
url
must begin with either 'http://' or 'https://'. If path
is a relative fs path, it is relative to the folder containing Cargo.toml
.
files
may be omitted if the url
or path
contains the full path to the .smithy
file.
All the following are (syntactically) valid model sources:
{ url: "https://example.com/interfaces/foo.smithy" }
{ url: "https://example.com/interfaces", files: [ "foo.smithy", "bar.smithy" ]}
{ path: "../interfaces/foo.smithy" }
{ path: "../interfaces", files: ["foo.smithy", "bar.smithy"]}
These are all equivalent:
{ path: "/usr/share/interfaces/timer.smithy" }
{ path: "/usr/share/interfaces", files: [ "timer.smithy" ] }
{ path: "/usr/share/interfaces/", files: [ "timer.smithy" ] }
If a model source structure contains no url base and no path base, the url for the github wasmcloud interface repo is used:
url: "https://cdn.jsdelivr.net/gh/wasmcloud/interfaces"
Why would the code generator need to load more than one smithy file? So that interfaces can share common symbols for data structures. Most smithy interfaces already import symbols from the namespace org.wasmcloud.model
, defined in wasmcloud-model.smithy
.
The bindgen tool resolves all symbols by assembling an in-memory schema model from all the smithy sources and namespaces, then traversing through the in-memory model, generating code only for the schema elements in the namespace declared in the second parameter of smithy_bindgen!
.
jsdelivr.net urls
cdn.jsdelivr.net
mirrors open source github repositories.
The url syntax can optionally include
a github branch, tag, or commit sha.
Common files
Wasmcloud common model files are always automatically included when compiling models
(If you've used codegen.toml
files, you may remember that they required all base models
to be specified explicitly.)
Namespace
Models may include symbols defined in other models via the use
command.
Only the symbols defined in the namespace (smithy_bindgen!
's second parameter)
will be included in the generated code.
Dependencies
~18–33MB
~538K SLoC