Skip to content

Commit

Permalink
Add resource type name argument to macro
Browse files Browse the repository at this point in the history
  • Loading branch information
filmor committed Jul 12, 2024
1 parent 884bb9e commit 58e5718
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
11 changes: 9 additions & 2 deletions rustler_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,15 @@ pub fn nif_untagged_enum(input: TokenStream) -> TokenStream {
/// }
/// ```
#[proc_macro_attribute]
pub fn resource_impl(_attr: TokenStream, item: TokenStream) -> TokenStream {
pub fn resource_impl(args: TokenStream, item: TokenStream) -> TokenStream {
let mut attributes = resource_impl::Attributes::default();

if !args.is_empty() {
let parser = syn::meta::parser(|meta| attributes.parse(meta));

syn::parse_macro_input!(args with parser);
}
let input = syn::parse_macro_input!(item as syn::ItemImpl);

resource_impl::transcoder_decorator(input).into()
resource_impl::transcoder_decorator(attributes, input).into()
}
57 changes: 50 additions & 7 deletions rustler_codegen/src/resource_impl.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
use proc_macro2::{Span, TokenStream};
use quote::quote;
use std::collections::HashSet;
use syn::{meta::ParseNestedMeta, LitBool, LitStr};

pub fn transcoder_decorator(mut input: syn::ItemImpl) -> TokenStream {
pub struct Attributes {
register: bool,
name: Option<String>,
}

impl Default for Attributes {
fn default() -> Self {
Self {
register: true,
name: None,
}
}
}

impl Attributes {
pub fn parse(&mut self, meta: ParseNestedMeta) -> syn::parse::Result<()> {
if meta.path.is_ident("register") {
let value: LitBool = meta.value()?.parse()?;
self.register = value.value;
Ok(())
} else if meta.path.is_ident("name") {
let value: LitStr = meta.value()?.parse()?;
self.name = Some(value.value());
Ok(())
} else {
Err(meta.error("Unsupported macro attribute. Expecting register or name."))
}
}
}

pub fn transcoder_decorator(attrs: Attributes, mut input: syn::ItemImpl) -> TokenStream {
// Should be `Resource` but will fail somewhere else anyway if it isn't.
// let (_, _trait_path, _) = input.trait_.unwrap();
let type_path = match *input.self_ty {
Expand Down Expand Up @@ -32,11 +63,23 @@ pub fn transcoder_decorator(mut input: syn::ItemImpl) -> TokenStream {
input.items.push(impl_item);
}

quote!(
#input
let mut res = quote!(#input);

if attrs.register {
if let Some(name) = attrs.name {
res.extend(quote!(
rustler::codegen_runtime::inventory::submit!(
rustler::codegen_runtime::ResourceRegistration::new::<#type_path>().with_name(#name)
);
));
} else {
res.extend(quote!(
rustler::codegen_runtime::inventory::submit!(
rustler::codegen_runtime::ResourceRegistration::new::<#type_path>()
);
));
}
}

rustler::codegen_runtime::inventory::submit!(
rustler::codegen_runtime::ResourceRegistration::new::<#type_path>()
);
)
res
}
2 changes: 1 addition & 1 deletion rustler_tests/native/rustler_test/src/test_resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct TestMonitorResource {
inner: Mutex<TestMonitorResourceInner>,
}

#[rustler::resource_impl(register = true)]
#[rustler::resource_impl(register = true, name = "monitor")]
impl Resource for TestMonitorResource {
fn down<'a>(&'a self, _env: Env<'a>, _pid: LocalPid, mon: Monitor) {
let mut inner = self.inner.lock().unwrap();
Expand Down

0 comments on commit 58e5718

Please sign in to comment.