in starlark_derive/src/render.rs [71:117]
fn render_attr(x: StarAttr) -> TokenStream {
let span = x.span();
let StarAttr {
name,
arg,
attrs,
return_type,
return_type_arg,
speculative_exec_safe,
body,
docstring,
} = x;
let name_str = ident_string(&name);
let docstring = match docstring {
Some(d) => quote_spanned!(span=> Some(#d.to_owned())),
None => quote_spanned!(span=> None),
};
quote_spanned! {
span=>
#( #attrs )*
#[allow(non_snake_case)] // Starlark doesn't have this convention
fn #name<'v>(
#[allow(unused_variables)]
this: starlark::values::Value<'v>,
heap: &'v starlark::values::Heap,
) -> anyhow::Result<starlark::values::Value<'v>> {
fn inner<'v>(
this: starlark::values::Value<'v>,
#[allow(unused_variables)]
heap: &'v starlark::values::Heap,
) -> #return_type {
#[allow(unused_variables)]
let this: #arg = match starlark::values::UnpackValue::unpack_value(this) {
None => return Err(starlark::values::ValueError::IncorrectParameterTypeNamedWithExpected(
"this".to_owned(),
<#arg as starlark::values::UnpackValue>::expected(),
this.get_type().to_owned(),
).into()),
Some(v) => v,
};
#body
}
Ok(heap.alloc(inner(this, heap)?))
}
globals_builder.set_attribute_fn(#name_str, #speculative_exec_safe, #docstring, stringify!(#return_type_arg).to_owned(), #name);
}
}