Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(neon-macros): Export Macro #1025

Merged
merged 11 commits into from
May 10, 2024
48 changes: 29 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/neon-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ edition = "2021"
proc-macro = true

[dependencies]
proc-macro2 = "1.0.79"
quote = "1.0.33"
syn = "2.0.39"
syn-mid = "0.6.0"
syn = { version = "2.0.57", features = ["full"] }
93 changes: 93 additions & 0 deletions crates/neon-macros/src/export/function/meta.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#[derive(Default)]
pub(crate) struct Meta {
pub(super) kind: Kind,
pub(super) name: Option<syn::LitStr>,
pub(super) json: bool,
pub(super) context: bool,
pub(super) result: bool,
}

#[derive(Default)]
pub(super) enum Kind {
#[default]
Normal,
Task,
}

impl Meta {
fn set_name(&mut self, meta: syn::meta::ParseNestedMeta) -> syn::Result<()> {
self.name = Some(meta.value()?.parse::<syn::LitStr>()?);

Ok(())
}

fn force_json(&mut self, _meta: syn::meta::ParseNestedMeta) -> syn::Result<()> {
self.json = true;

Ok(())
}

fn force_context(&mut self, meta: syn::meta::ParseNestedMeta) -> syn::Result<()> {
match self.kind {
Kind::Normal => {}
Kind::Task => return Err(meta.error(super::TASK_CX_ERROR)),
}

self.context = true;

Ok(())
}

fn force_result(&mut self, _meta: syn::meta::ParseNestedMeta) -> syn::Result<()> {
self.result = true;

Ok(())
}

fn make_task(&mut self, meta: syn::meta::ParseNestedMeta) -> syn::Result<()> {
if self.context {
return Err(meta.error(super::TASK_CX_ERROR));
}

self.kind = Kind::Task;

Ok(())
}
}

pub(crate) struct Parser;

impl syn::parse::Parser for Parser {
type Output = Meta;

fn parse2(self, tokens: proc_macro2::TokenStream) -> syn::Result<Self::Output> {
let mut attr = Meta::default();
let parser = syn::meta::parser(|meta| {
if meta.path.is_ident("name") {
return attr.set_name(meta);
}

if meta.path.is_ident("json") {
return attr.force_json(meta);
}

if meta.path.is_ident("context") {
kjvalencik marked this conversation as resolved.
Show resolved Hide resolved
return attr.force_context(meta);
}

if meta.path.is_ident("result") {
return attr.force_result(meta);
}

if meta.path.is_ident("task") {
return attr.make_task(meta);
}

Err(meta.error("unsupported property"))
});

parser.parse2(tokens)?;

Ok(attr)
}
}
Loading
Loading