Skip to content

Commit

Permalink
use dedicated attributes for derive(Any) functions and derive
Browse files Browse the repository at this point in the history
  • Loading branch information
ModProg committed Aug 3, 2023
1 parent a5d1fcf commit 877ebf3
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 75 deletions.
157 changes: 84 additions & 73 deletions crates/rune-macros/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,22 +136,19 @@ impl TypeProtocol {
},
"STRING_DISPLAY" => quote_spanned! {self.protocol.span()=>
module.associated_function(rune::runtime::Protocol::STRING_DISPLAY, |this: &Self, buf: &mut String| {
use ::std::fmt::Write as _;
::std::write!(buf, "{this}")
use ::core::fmt::Write as _;
::core::write!(buf, "{this}")
})?;
},
"STRING_DEBUG" => quote_spanned! {self.protocol.span()=>
module.associated_function(rune::runtime::Protocol::STRING_DEBUG, |this: &Self, buf: &mut String| {
use ::std::fmt::Write as _;
::std::write!(buf, "{this:?}")
use ::core::fmt::Write as _;
::core::write!(buf, "{this:?}")
})?;
},
_ => syn::Error::new_spanned(
&self.protocol,
format!(
"`{}` is not a protocol supported for automatic generation on a type",
self.protocol
),
format!("Rune protocol `{}` cannot be derived", self.protocol),
)
.to_compile_error(),
}
Expand Down Expand Up @@ -455,7 +452,7 @@ impl Context {
let mut error = false;
let mut attr = TypeAttr::default();

for a in input {
'attrs: for a in input {
if a.path().is_ident("doc") {
if let syn::Meta::NameValue(meta) = &a.meta {
attr.docs.push(meta.value.clone());
Expand All @@ -464,72 +461,86 @@ impl Context {
continue;
}

if a.path() == RUNE {
let result = a.parse_nested_meta(|meta| {
if meta.path == PARSE {
// Parse `#[rune(parse = "..")]`
meta.input.parse::<Token![=]>()?;
let s: syn::LitStr = meta.input.parse()?;

match s.value().as_str() {
"meta_only" => {
attr.parse = ParseKind::MetaOnly;
}
other => {
return Err(syn::Error::new(
meta.input.span(),
format!(
"Unsupported `#[rune(parse = ..)]` argument `{}`",
other
),
));
}
};
} else if meta.path == ITEM {
// Parse `#[rune(item = "..")]`
meta.input.parse::<Token![=]>()?;
attr.item = Some(meta.input.parse()?);
} else if meta.path == NAME {
// Parse `#[rune(name = "..")]`
meta.input.parse::<Token![=]>()?;
attr.name = Some(meta.input.parse()?);
} else if meta.path == MODULE {
// Parse `#[rune(module = <path>)]`
meta.input.parse::<Token![=]>()?;
attr.module = Some(parse_path_compat(meta.input)?);
} else if meta.path == INSTALL_WITH {
// Parse `#[rune(install_with = <path>)]`
meta.input.parse::<Token![=]>()?;
attr.install_with = Some(parse_path_compat(meta.input)?);
} else if meta.path == CONSTRUCTOR {
attr.constructor = true;
} else if meta.path == PROTOCOLS {
// Parse `#[rune(protocols(<protocol>,*))]`
let protocols;
syn::parenthesized!(protocols in meta.input);
attr.protocols
.extend(protocols.parse_terminated(TypeProtocol::parse, Token![,])?);
} else if meta.path == FUNCTIONS {
// Parse `#[rune(functions(<function>,*))]`
let functions;
syn::parenthesized!(functions in meta.input);
attr.functions
.extend(functions.parse_terminated(syn::Path::parse, Token![,])?);
} else {
return Err(syn::Error::new_spanned(
&meta.path,
"Unsupported type attribute",
));
}
let err = 'error: {
if a.path() == RUNE {
let result = a.parse_nested_meta(|meta| {
if meta.path == PARSE {
// Parse `#[rune(parse = "..")]`
meta.input.parse::<Token![=]>()?;
let s: syn::LitStr = meta.input.parse()?;

match s.value().as_str() {
"meta_only" => {
attr.parse = ParseKind::MetaOnly;
}
other => {
return Err(syn::Error::new(
meta.input.span(),
format!(
"Unsupported `#[rune(parse = ..)]` argument `{}`",
other
),
));
}
};
} else if meta.path == ITEM {
// Parse `#[rune(item = "..")]`
meta.input.parse::<Token![=]>()?;
attr.item = Some(meta.input.parse()?);
} else if meta.path == NAME {
// Parse `#[rune(name = "..")]`
meta.input.parse::<Token![=]>()?;
attr.name = Some(meta.input.parse()?);
} else if meta.path == MODULE {
// Parse `#[rune(module = <path>)]`
meta.input.parse::<Token![=]>()?;
attr.module = Some(parse_path_compat(meta.input)?);
} else if meta.path == INSTALL_WITH {
// Parse `#[rune(install_with = <path>)]`
meta.input.parse::<Token![=]>()?;
attr.install_with = Some(parse_path_compat(meta.input)?);
} else if meta.path == CONSTRUCTOR {
attr.constructor = true;
} else {
return Err(syn::Error::new_spanned(
&meta.path,
"Unsupported type attribute",
));
}

Ok(())
});
Ok(())
});

if let Err(e) = result {
error = true;
self.error(e);
};
}
if let Err(e) = result {
break 'error e;
};
}

if a.path() == RUNE_DERIVE {
attr.protocols.extend(
match a.parse_args_with(Punctuated::<_, Token![,]>::parse_terminated) {
Ok(it) => it,
Err(err) => {
break 'error err;
}
},
);
}

if a.path() == RUNE_FUNCTIONS {
attr.functions.extend(
match a.parse_args_with(Punctuated::<_, Token![,]>::parse_terminated) {
Ok(it) => it,
Err(err) => {
break 'error err;
}
},
);
}
continue 'attrs;
};
error = true;
self.error(err);
}

if error {
Expand Down
4 changes: 2 additions & 2 deletions crates/rune-macros/src/internals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use std::fmt;
pub struct Symbol(&'static str);

pub const RUNE: Symbol = Symbol("rune");
pub const RUNE_DERIVE: Symbol = Symbol("rune_derive");
pub const RUNE_FUNCTIONS: Symbol = Symbol("rune_functions");
pub const ID: Symbol = Symbol("id");
pub const SKIP: Symbol = Symbol("skip");
pub const ITER: Symbol = Symbol("iter");
Expand All @@ -19,8 +21,6 @@ pub const NAME: Symbol = Symbol("name");
pub const ITEM: Symbol = Symbol("item");
pub const MODULE: Symbol = Symbol("module");
pub const INSTALL_WITH: Symbol = Symbol("install_with");
pub const PROTOCOLS: Symbol = Symbol("protocols");
pub const FUNCTIONS: Symbol = Symbol("functions");

pub const CONSTRUCTOR: Symbol = Symbol("constructor");
pub const GET: Symbol = Symbol("get");
Expand Down

0 comments on commit 877ebf3

Please sign in to comment.