Avoid parsing function bodies for a better rust-analyzer experience.

This commit is contained in:
Diggory Blake 2021-10-22 15:01:40 +01:00
parent 15cafb3590
commit ea408f7ab6
No known key found for this signature in database
GPG key ID: E6BDFA83146ABD40
3 changed files with 50 additions and 9 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "sqlxmq" name = "sqlxmq"
version = "0.3.2" version = "0.3.3"
authors = ["Diggory Blake <diggsey@googlemail.com>"] authors = ["Diggory Blake <diggsey@googlemail.com>"]
edition = "2018" edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
@ -23,7 +23,7 @@ uuid = { version = "0.8.2", features = ["v4"] }
log = "0.4.14" log = "0.4.14"
serde_json = "1.0.64" serde_json = "1.0.64"
serde = "1.0.124" serde = "1.0.124"
sqlxmq_macros = { version = "0.3.2", path = "sqlxmq_macros" } sqlxmq_macros = { version = "0.3.3", path = "sqlxmq_macros" }
anymap2 = "0.13.0" anymap2 = "0.13.0"
[features] [features]

View file

@ -1,6 +1,6 @@
[package] [package]
name = "sqlxmq_macros" name = "sqlxmq_macros"
version = "0.3.2" version = "0.3.3"
authors = ["Diggory Blake <diggsey@googlemail.com>"] authors = ["Diggory Blake <diggsey@googlemail.com>"]
edition = "2018" edition = "2018"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
@ -14,5 +14,6 @@ documentation = "https://docs.rs/sqlxmq"
proc-macro = true proc-macro = true
[dependencies] [dependencies]
syn = { version = "1.0.64", features = ["full"] } syn = { version = "1.0.80", features = ["full"] }
quote = "1.0.9" quote = "1.0.10"
proc-macro2 = "1.0.30"

View file

@ -6,10 +6,12 @@
use std::mem; use std::mem;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::quote; use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{ use syn::{
parse_macro_input, parse_quote, AttributeArgs, Error, ItemFn, Lit, Meta, NestedMeta, Path, parse::{Parse, ParseStream},
Result, Visibility, parse_macro_input, parse_quote, AttrStyle, Attribute, AttributeArgs, Error, Lit, Meta,
NestedMeta, Path, Result, Signature, Visibility,
}; };
#[derive(Default)] #[derive(Default)]
@ -90,6 +92,44 @@ fn interpret_job_arg(options: &mut JobOptions, arg: NestedMeta) -> Result<()> {
Ok(()) Ok(())
} }
#[derive(Clone)]
struct MaybeItemFn {
attrs: Vec<Attribute>,
vis: Visibility,
sig: Signature,
block: TokenStream2,
}
/// This parses a `TokenStream` into a `MaybeItemFn`
/// (just like `ItemFn`, but skips parsing the body).
impl Parse for MaybeItemFn {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let attrs = input.call(syn::Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
let sig: Signature = input.parse()?;
let block: TokenStream2 = input.parse()?;
Ok(Self {
attrs,
vis,
sig,
block,
})
}
}
impl ToTokens for MaybeItemFn {
fn to_tokens(&self, tokens: &mut TokenStream2) {
tokens.append_all(
self.attrs
.iter()
.filter(|attr| matches!(attr.style, AttrStyle::Outer)),
);
self.vis.to_tokens(tokens);
self.sig.to_tokens(tokens);
self.block.to_tokens(tokens);
}
}
/// Marks a function as being a background job. /// Marks a function as being a background job.
/// ///
/// The first argument to the function must have type `CurrentJob`. /// The first argument to the function must have type `CurrentJob`.
@ -181,7 +221,7 @@ fn interpret_job_arg(options: &mut JobOptions, arg: NestedMeta) -> Result<()> {
#[proc_macro_attribute] #[proc_macro_attribute]
pub fn job(attr: TokenStream, item: TokenStream) -> TokenStream { pub fn job(attr: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attr as AttributeArgs); let args = parse_macro_input!(attr as AttributeArgs);
let mut inner_fn = parse_macro_input!(item as ItemFn); let mut inner_fn = parse_macro_input!(item as MaybeItemFn);
let mut options = JobOptions::default(); let mut options = JobOptions::default();
let mut errors = Vec::new(); let mut errors = Vec::new();