Update world-selection in bindgen! macro (#5779)
* Update world-selection in `bindgen!` macro Inspired by bytecodealliance/wit-bindgen#494 specifying a world or document to bindgen is now optional as it's inferred if there's only one `default world` in a package's documents. * Add cargo-vet entry
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -4110,9 +4110,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e0fe225a32528b42a7037add1b5ed1dff83288f21a067007b34565ce87fc2c7"
|
||||
checksum = "a84965789410bf21087f5a352703142f77b9b4d1478764c3f33a1ea8c7101f40"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
|
||||
@@ -169,7 +169,7 @@ wasmprinter = "0.2.50"
|
||||
wasm-encoder = "0.23.0"
|
||||
wasm-smith = "0.12.1"
|
||||
wasm-mutate = "0.2.17"
|
||||
wit-parser = "0.6.0"
|
||||
wit-parser = "0.6.1"
|
||||
windows-sys = "0.45.0"
|
||||
env_logger = "0.9"
|
||||
rustix = "0.36.7"
|
||||
|
||||
@@ -46,14 +46,14 @@ impl Parse for Config {
|
||||
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||
let call_site = Span::call_site();
|
||||
let mut opts = Opts::default();
|
||||
let mut world = None;
|
||||
let mut source = None;
|
||||
let mut world = None;
|
||||
|
||||
let document = if input.peek(token::Brace) {
|
||||
if input.peek(token::Brace) {
|
||||
let content;
|
||||
syn::braced!(content in input);
|
||||
let fields = Punctuated::<Opt, Token![,]>::parse_terminated(&content)?;
|
||||
let mut document = None;
|
||||
let mut world = None;
|
||||
for field in fields.into_pairs() {
|
||||
match field.into_value() {
|
||||
Opt::Path(s) => {
|
||||
@@ -63,10 +63,10 @@ impl Parse for Config {
|
||||
source = Some(Source::Path(s.value()));
|
||||
}
|
||||
Opt::World(s) => {
|
||||
if document.is_some() {
|
||||
return Err(Error::new(s.span(), "cannot specify second document"));
|
||||
if world.is_some() {
|
||||
return Err(Error::new(s.span(), "cannot specify second world"));
|
||||
}
|
||||
document = Some(parse_doc(&s.value(), &mut world));
|
||||
world = Some(s.value());
|
||||
}
|
||||
Opt::Inline(s) => {
|
||||
if source.is_some() {
|
||||
@@ -79,43 +79,17 @@ impl Parse for Config {
|
||||
Opt::TrappableErrorType(val) => opts.trappable_error_type = val,
|
||||
}
|
||||
}
|
||||
match (document, &source) {
|
||||
(Some(doc), _) => doc,
|
||||
(None, Some(Source::Inline(_))) => "macro-input".to_string(),
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
call_site,
|
||||
"must specify a `world` to generate bindings for",
|
||||
))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let document = input.parse::<syn::LitStr>()?;
|
||||
world = input.parse::<Option<syn::LitStr>>()?.map(|s| s.value());
|
||||
if input.parse::<Option<syn::token::In>>()?.is_some() {
|
||||
source = Some(Source::Path(input.parse::<syn::LitStr>()?.value()));
|
||||
}
|
||||
parse_doc(&document.value(), &mut world)
|
||||
};
|
||||
}
|
||||
let (resolve, pkg, files) =
|
||||
parse_source(&source).map_err(|err| Error::new(call_site, format!("{err:?}")))?;
|
||||
let doc = resolve.packages[pkg]
|
||||
.documents
|
||||
.get(&document)
|
||||
.copied()
|
||||
.ok_or_else(|| {
|
||||
Error::new(call_site, format!("no document named `{document}` found"))
|
||||
})?;
|
||||
|
||||
let world = match &world {
|
||||
Some(name) => resolve.documents[doc]
|
||||
.worlds
|
||||
.get(name)
|
||||
.copied()
|
||||
.ok_or_else(|| Error::new(call_site, format!("no world named `{name}` found")))?,
|
||||
None => resolve.documents[doc].default_world.ok_or_else(|| {
|
||||
Error::new(call_site, format!("no default world found in `{document}`"))
|
||||
})?,
|
||||
};
|
||||
let world = resolve
|
||||
.select_world(pkg, world.as_deref())
|
||||
.map_err(|e| Error::new(call_site, format!("{e:?}")))?;
|
||||
Ok(Config {
|
||||
opts,
|
||||
resolve,
|
||||
@@ -152,16 +126,6 @@ fn parse_source(source: &Option<Source>) -> anyhow::Result<(Resolve, PackageId,
|
||||
Ok((resolve, pkg, files))
|
||||
}
|
||||
|
||||
fn parse_doc(s: &str, world: &mut Option<String>) -> String {
|
||||
match s.find('.') {
|
||||
Some(pos) => {
|
||||
*world = Some(s[pos + 1..].to_string());
|
||||
s[..pos].to_string()
|
||||
}
|
||||
None => s.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
mod kw {
|
||||
syn::custom_keyword!(inline);
|
||||
syn::custom_keyword!(path);
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
macro_rules! gentest {
|
||||
($id:ident $name:tt $path:tt) => {
|
||||
mod $id {
|
||||
mod sugar {
|
||||
wasmtime::component::bindgen!(in $path);
|
||||
}
|
||||
mod normal {
|
||||
wasmtime::component::bindgen!($name in $path);
|
||||
}
|
||||
mod async_ {
|
||||
wasmtime::component::bindgen!({
|
||||
world: $name,
|
||||
path: $path,
|
||||
async: true,
|
||||
});
|
||||
}
|
||||
mod tracing {
|
||||
wasmtime::component::bindgen!({
|
||||
world: $name,
|
||||
path: $path,
|
||||
world: $name,
|
||||
tracing: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ pub(crate) use self::store::ComponentStoreData;
|
||||
/// use wasmtime::component::*;
|
||||
/// use wasmtime::{Config, Engine, Store};
|
||||
///
|
||||
/// bindgen!("my-component");
|
||||
/// bindgen!();
|
||||
///
|
||||
/// struct MyState {
|
||||
/// name: String,
|
||||
@@ -170,7 +170,7 @@ pub(crate) use self::store::ComponentStoreData;
|
||||
/// use wasmtime::component::*;
|
||||
/// use wasmtime::{Config, Engine, Store};
|
||||
///
|
||||
/// bindgen!("my-component");
|
||||
/// bindgen!();
|
||||
///
|
||||
/// struct MyState {
|
||||
/// // ...
|
||||
@@ -223,6 +223,11 @@ pub(crate) use self::store::ComponentStoreData;
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look
|
||||
/// // for a `default world` in its documents. There must be exactly one
|
||||
/// // `default world` for this to succeed.
|
||||
/// bindgen!();
|
||||
///
|
||||
/// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look
|
||||
/// // for the document `foo`, which must have a `default world` contained
|
||||
/// // within it.
|
||||
/// bindgen!("foo");
|
||||
@@ -232,6 +237,7 @@ pub(crate) use self::store::ComponentStoreData;
|
||||
/// bindgen!("foo.bar");
|
||||
///
|
||||
/// // Parse the folder `other/wit/folder` adjacent to `Cargo.toml`.
|
||||
/// bindgen!(in "other/wit/folder");
|
||||
/// bindgen!("foo" in "other/wit/folder");
|
||||
/// bindgen!("foo.bar" in "other/wit/folder");
|
||||
///
|
||||
@@ -245,8 +251,9 @@ pub(crate) use self::store::ComponentStoreData;
|
||||
/// ```rust,ignore
|
||||
/// bindgen!({
|
||||
/// world: "foo", // or "foo.bar", same as in `bindgen!("foo")`
|
||||
/// // not needed if `path` has one `default world`
|
||||
///
|
||||
/// // same as in `bindgen!("foo" in "other/wit/folder")
|
||||
/// // same as in `bindgen!(in "other/wit/folder")
|
||||
/// path: "other/wit/folder",
|
||||
///
|
||||
/// // Instead of `path` the WIT document can be provided inline if
|
||||
|
||||
@@ -1442,3 +1442,9 @@ criteria = "safe-to-deploy"
|
||||
version = "0.6.0"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
[[audits.wit-parser]]
|
||||
who = "Alex Crichton <alex@alexcrichton.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
version = "0.6.1"
|
||||
notes = "The Bytecode Alliance is the author of this crate."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user