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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user