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]]
|
[[package]]
|
||||||
name = "wit-parser"
|
name = "wit-parser"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e0fe225a32528b42a7037add1b5ed1dff83288f21a067007b34565ce87fc2c7"
|
checksum = "a84965789410bf21087f5a352703142f77b9b4d1478764c3f33a1ea8c7101f40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"id-arena",
|
"id-arena",
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ wasmprinter = "0.2.50"
|
|||||||
wasm-encoder = "0.23.0"
|
wasm-encoder = "0.23.0"
|
||||||
wasm-smith = "0.12.1"
|
wasm-smith = "0.12.1"
|
||||||
wasm-mutate = "0.2.17"
|
wasm-mutate = "0.2.17"
|
||||||
wit-parser = "0.6.0"
|
wit-parser = "0.6.1"
|
||||||
windows-sys = "0.45.0"
|
windows-sys = "0.45.0"
|
||||||
env_logger = "0.9"
|
env_logger = "0.9"
|
||||||
rustix = "0.36.7"
|
rustix = "0.36.7"
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ impl Parse for Config {
|
|||||||
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
fn parse(input: ParseStream<'_>) -> Result<Self> {
|
||||||
let call_site = Span::call_site();
|
let call_site = Span::call_site();
|
||||||
let mut opts = Opts::default();
|
let mut opts = Opts::default();
|
||||||
let mut world = None;
|
|
||||||
let mut source = None;
|
let mut source = None;
|
||||||
|
let mut world = None;
|
||||||
|
|
||||||
let document = if input.peek(token::Brace) {
|
if input.peek(token::Brace) {
|
||||||
let content;
|
let content;
|
||||||
syn::braced!(content in input);
|
syn::braced!(content in input);
|
||||||
let fields = Punctuated::<Opt, Token![,]>::parse_terminated(&content)?;
|
let fields = Punctuated::<Opt, Token![,]>::parse_terminated(&content)?;
|
||||||
let mut document = None;
|
let mut world = None;
|
||||||
for field in fields.into_pairs() {
|
for field in fields.into_pairs() {
|
||||||
match field.into_value() {
|
match field.into_value() {
|
||||||
Opt::Path(s) => {
|
Opt::Path(s) => {
|
||||||
@@ -63,10 +63,10 @@ impl Parse for Config {
|
|||||||
source = Some(Source::Path(s.value()));
|
source = Some(Source::Path(s.value()));
|
||||||
}
|
}
|
||||||
Opt::World(s) => {
|
Opt::World(s) => {
|
||||||
if document.is_some() {
|
if world.is_some() {
|
||||||
return Err(Error::new(s.span(), "cannot specify second document"));
|
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) => {
|
Opt::Inline(s) => {
|
||||||
if source.is_some() {
|
if source.is_some() {
|
||||||
@@ -79,43 +79,17 @@ impl Parse for Config {
|
|||||||
Opt::TrappableErrorType(val) => opts.trappable_error_type = val,
|
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 {
|
} 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() {
|
if input.parse::<Option<syn::token::In>>()?.is_some() {
|
||||||
source = Some(Source::Path(input.parse::<syn::LitStr>()?.value()));
|
source = Some(Source::Path(input.parse::<syn::LitStr>()?.value()));
|
||||||
}
|
}
|
||||||
parse_doc(&document.value(), &mut world)
|
}
|
||||||
};
|
|
||||||
let (resolve, pkg, files) =
|
let (resolve, pkg, files) =
|
||||||
parse_source(&source).map_err(|err| Error::new(call_site, format!("{err:?}")))?;
|
parse_source(&source).map_err(|err| Error::new(call_site, format!("{err:?}")))?;
|
||||||
let doc = resolve.packages[pkg]
|
let world = resolve
|
||||||
.documents
|
.select_world(pkg, world.as_deref())
|
||||||
.get(&document)
|
.map_err(|e| Error::new(call_site, format!("{e:?}")))?;
|
||||||
.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}`"))
|
|
||||||
})?,
|
|
||||||
};
|
|
||||||
Ok(Config {
|
Ok(Config {
|
||||||
opts,
|
opts,
|
||||||
resolve,
|
resolve,
|
||||||
@@ -152,16 +126,6 @@ fn parse_source(source: &Option<Source>) -> anyhow::Result<(Resolve, PackageId,
|
|||||||
Ok((resolve, pkg, files))
|
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 {
|
mod kw {
|
||||||
syn::custom_keyword!(inline);
|
syn::custom_keyword!(inline);
|
||||||
syn::custom_keyword!(path);
|
syn::custom_keyword!(path);
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
macro_rules! gentest {
|
macro_rules! gentest {
|
||||||
($id:ident $name:tt $path:tt) => {
|
($id:ident $name:tt $path:tt) => {
|
||||||
mod $id {
|
mod $id {
|
||||||
|
mod sugar {
|
||||||
|
wasmtime::component::bindgen!(in $path);
|
||||||
|
}
|
||||||
mod normal {
|
mod normal {
|
||||||
wasmtime::component::bindgen!($name in $path);
|
wasmtime::component::bindgen!($name in $path);
|
||||||
}
|
}
|
||||||
mod async_ {
|
mod async_ {
|
||||||
wasmtime::component::bindgen!({
|
wasmtime::component::bindgen!({
|
||||||
world: $name,
|
|
||||||
path: $path,
|
path: $path,
|
||||||
async: true,
|
async: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
mod tracing {
|
mod tracing {
|
||||||
wasmtime::component::bindgen!({
|
wasmtime::component::bindgen!({
|
||||||
world: $name,
|
|
||||||
path: $path,
|
path: $path,
|
||||||
|
world: $name,
|
||||||
tracing: true,
|
tracing: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ pub(crate) use self::store::ComponentStoreData;
|
|||||||
/// use wasmtime::component::*;
|
/// use wasmtime::component::*;
|
||||||
/// use wasmtime::{Config, Engine, Store};
|
/// use wasmtime::{Config, Engine, Store};
|
||||||
///
|
///
|
||||||
/// bindgen!("my-component");
|
/// bindgen!();
|
||||||
///
|
///
|
||||||
/// struct MyState {
|
/// struct MyState {
|
||||||
/// name: String,
|
/// name: String,
|
||||||
@@ -170,7 +170,7 @@ pub(crate) use self::store::ComponentStoreData;
|
|||||||
/// use wasmtime::component::*;
|
/// use wasmtime::component::*;
|
||||||
/// use wasmtime::{Config, Engine, Store};
|
/// use wasmtime::{Config, Engine, Store};
|
||||||
///
|
///
|
||||||
/// bindgen!("my-component");
|
/// bindgen!();
|
||||||
///
|
///
|
||||||
/// struct MyState {
|
/// struct MyState {
|
||||||
/// // ...
|
/// // ...
|
||||||
@@ -223,6 +223,11 @@ pub(crate) use self::store::ComponentStoreData;
|
|||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// // Parse the `wit/` folder adjacent to this crate's `Cargo.toml` and look
|
/// // 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
|
/// // for the document `foo`, which must have a `default world` contained
|
||||||
/// // within it.
|
/// // within it.
|
||||||
/// bindgen!("foo");
|
/// bindgen!("foo");
|
||||||
@@ -232,6 +237,7 @@ pub(crate) use self::store::ComponentStoreData;
|
|||||||
/// bindgen!("foo.bar");
|
/// bindgen!("foo.bar");
|
||||||
///
|
///
|
||||||
/// // Parse the folder `other/wit/folder` adjacent to `Cargo.toml`.
|
/// // Parse the folder `other/wit/folder` adjacent to `Cargo.toml`.
|
||||||
|
/// bindgen!(in "other/wit/folder");
|
||||||
/// bindgen!("foo" in "other/wit/folder");
|
/// bindgen!("foo" in "other/wit/folder");
|
||||||
/// bindgen!("foo.bar" in "other/wit/folder");
|
/// bindgen!("foo.bar" in "other/wit/folder");
|
||||||
///
|
///
|
||||||
@@ -245,8 +251,9 @@ pub(crate) use self::store::ComponentStoreData;
|
|||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// bindgen!({
|
/// bindgen!({
|
||||||
/// world: "foo", // or "foo.bar", same as in `bindgen!("foo")`
|
/// 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",
|
/// path: "other/wit/folder",
|
||||||
///
|
///
|
||||||
/// // Instead of `path` the WIT document can be provided inline if
|
/// // Instead of `path` the WIT document can be provided inline if
|
||||||
|
|||||||
@@ -1442,3 +1442,9 @@ criteria = "safe-to-deploy"
|
|||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
notes = "The Bytecode Alliance is the author of this crate."
|
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